diff options
author | Alex Ray <aray@google.com> | 2013-07-30 12:48:57 -0700 |
---|---|---|
committer | Alex Ray <aray@google.com> | 2013-07-31 13:48:57 -0700 |
commit | b304edb0b1f45ec7d4f10cfbff1b91f50bca86e4 (patch) | |
tree | 954f7258776d0f5c2683b85ed6307e6cc3ac2b30 | |
parent | 8776c34ca2e6cc92c453f5a83e11bcb67b0d5aff (diff) | |
download | frameworks_native-b304edb0b1f45ec7d4f10cfbff1b91f50bca86e4.zip frameworks_native-b304edb0b1f45ec7d4f10cfbff1b91f50bca86e4.tar.gz frameworks_native-b304edb0b1f45ec7d4f10cfbff1b91f50bca86e4.tar.bz2 |
remove libutils
libutils is being moved from frameworks/native/ to system/core/ in order
to facilitate native C++ platform (non-frameworks) code.
Change-Id: I44089fb960591a40b8a9c30faabb10459d107d71
88 files changed, 0 insertions, 17758 deletions
diff --git a/include/utils/AndroidThreads.h b/include/utils/AndroidThreads.h deleted file mode 100644 index 4eee14d..0000000 --- a/include/utils/AndroidThreads.h +++ /dev/null @@ -1,128 +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 _LIBS_UTILS_ANDROID_THREADS_H -#define _LIBS_UTILS_ANDROID_THREADS_H - -#include <stdint.h> -#include <sys/types.h> - -#if defined(HAVE_PTHREADS) -# include <pthread.h> -#endif - -#include <utils/ThreadDefs.h> - -// --------------------------------------------------------------------------- -// C API - -#ifdef __cplusplus -extern "C" { -#endif - -// Create and run a new thread. -extern int androidCreateThread(android_thread_func_t, void *); - -// Create thread with lots of parameters -extern int androidCreateThreadEtc(android_thread_func_t entryFunction, - void *userData, - const char* threadName, - int32_t threadPriority, - size_t threadStackSize, - android_thread_id_t *threadId); - -// Get some sort of unique identifier for the current thread. -extern android_thread_id_t androidGetThreadId(); - -// Low-level thread creation -- never creates threads that can -// interact with the Java VM. -extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction, - void *userData, - const char* threadName, - int32_t threadPriority, - size_t threadStackSize, - android_thread_id_t *threadId); - -// set the same of the running thread -extern void androidSetThreadName(const char* name); - -// Used by the Java Runtime to control how threads are created, so that -// they can be proper and lovely Java threads. -typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction, - void *userData, - const char* threadName, - int32_t threadPriority, - size_t threadStackSize, - android_thread_id_t *threadId); - -extern void androidSetCreateThreadFunc(android_create_thread_fn func); - -// ------------------------------------------------------------------ -// Extra functions working with raw pids. - -// Get pid for the current thread. -extern pid_t androidGetTid(); - -#ifdef HAVE_ANDROID_OS -// Change the priority AND scheduling group of a particular thread. The priority -// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION -// if the priority set failed, else another value if just the group set failed; -// in either case errno is set. Thread ID zero means current thread. -extern int androidSetThreadPriority(pid_t tid, int prio); - -// Get the current priority of a particular thread. Returns one of the -// ANDROID_PRIORITY constants or a negative result in case of error. -extern int androidGetThreadPriority(pid_t tid); -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -// ---------------------------------------------------------------------------- -// C++ API -#ifdef __cplusplus -namespace android { -// ---------------------------------------------------------------------------- - -// Create and run a new thread. -inline bool createThread(thread_func_t f, void *a) { - return androidCreateThread(f, a) ? true : false; -} - -// Create thread with lots of parameters -inline bool createThreadEtc(thread_func_t entryFunction, - void *userData, - const char* threadName = "android:unnamed_thread", - int32_t threadPriority = PRIORITY_DEFAULT, - size_t threadStackSize = 0, - thread_id_t *threadId = 0) -{ - return androidCreateThreadEtc(entryFunction, userData, threadName, - threadPriority, threadStackSize, threadId) ? true : false; -} - -// Get some sort of unique identifier for the current thread. -inline thread_id_t getThreadId() { - return androidGetThreadId(); -} - -// ---------------------------------------------------------------------------- -}; // namespace android -#endif // __cplusplus -// ---------------------------------------------------------------------------- - -#endif // _LIBS_UTILS_ANDROID_THREADS_H diff --git a/include/utils/Atomic.h b/include/utils/Atomic.h deleted file mode 100644 index 7eb476c..0000000 --- a/include/utils/Atomic.h +++ /dev/null @@ -1,22 +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_UTILS_ATOMIC_H -#define ANDROID_UTILS_ATOMIC_H - -#include <cutils/atomic.h> - -#endif // ANDROID_UTILS_ATOMIC_H diff --git a/include/utils/BasicHashtable.h b/include/utils/BasicHashtable.h deleted file mode 100644 index c235d62..0000000 --- a/include/utils/BasicHashtable.h +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (C) 2011 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_BASIC_HASHTABLE_H -#define ANDROID_BASIC_HASHTABLE_H - -#include <stdint.h> -#include <sys/types.h> -#include <utils/SharedBuffer.h> -#include <utils/TypeHelpers.h> - -namespace android { - -/* Implementation type. Nothing to see here. */ -class BasicHashtableImpl { -protected: - struct Bucket { - // The collision flag indicates that the bucket is part of a collision chain - // such that at least two entries both hash to this bucket. When true, we - // may need to seek further along the chain to find the entry. - static const uint32_t COLLISION = 0x80000000UL; - - // The present flag indicates that the bucket contains an initialized entry value. - static const uint32_t PRESENT = 0x40000000UL; - - // Mask for 30 bits worth of the hash code that are stored within the bucket to - // speed up lookups and rehashing by eliminating the need to recalculate the - // hash code of the entry's key. - static const uint32_t HASH_MASK = 0x3fffffffUL; - - // Combined value that stores the collision and present flags as well as - // a 30 bit hash code. - uint32_t cookie; - - // Storage for the entry begins here. - char entry[0]; - }; - - BasicHashtableImpl(size_t entrySize, bool hasTrivialDestructor, - size_t minimumInitialCapacity, float loadFactor); - BasicHashtableImpl(const BasicHashtableImpl& other); - virtual ~BasicHashtableImpl(); - - void dispose(); - - inline void edit() { - if (mBuckets && !SharedBuffer::bufferFromData(mBuckets)->onlyOwner()) { - clone(); - } - } - - void setTo(const BasicHashtableImpl& other); - void clear(); - - ssize_t next(ssize_t index) const; - ssize_t find(ssize_t index, hash_t hash, const void* __restrict__ key) const; - size_t add(hash_t hash, const void* __restrict__ entry); - void removeAt(size_t index); - void rehash(size_t minimumCapacity, float loadFactor); - - const size_t mBucketSize; // number of bytes per bucket including the entry - const bool mHasTrivialDestructor; // true if the entry type does not require destruction - size_t mCapacity; // number of buckets that can be filled before exceeding load factor - float mLoadFactor; // load factor - size_t mSize; // number of elements actually in the table - size_t mFilledBuckets; // number of buckets for which collision or present is true - size_t mBucketCount; // number of slots in the mBuckets array - void* mBuckets; // array of buckets, as a SharedBuffer - - inline const Bucket& bucketAt(const void* __restrict__ buckets, size_t index) const { - return *reinterpret_cast<const Bucket*>( - static_cast<const uint8_t*>(buckets) + index * mBucketSize); - } - - inline Bucket& bucketAt(void* __restrict__ buckets, size_t index) const { - return *reinterpret_cast<Bucket*>(static_cast<uint8_t*>(buckets) + index * mBucketSize); - } - - virtual bool compareBucketKey(const Bucket& bucket, const void* __restrict__ key) const = 0; - virtual void initializeBucketEntry(Bucket& bucket, const void* __restrict__ entry) const = 0; - virtual void destroyBucketEntry(Bucket& bucket) const = 0; - -private: - void clone(); - - // Allocates a bucket array as a SharedBuffer. - void* allocateBuckets(size_t count) const; - - // Releases a bucket array's associated SharedBuffer. - void releaseBuckets(void* __restrict__ buckets, size_t count) const; - - // Destroys the contents of buckets (invokes destroyBucketEntry for each - // populated bucket if needed). - void destroyBuckets(void* __restrict__ buckets, size_t count) const; - - // Copies the content of buckets (copies the cookie and invokes copyBucketEntry - // for each populated bucket if needed). - void copyBuckets(const void* __restrict__ fromBuckets, - void* __restrict__ toBuckets, size_t count) const; - - // Determines the appropriate size of a bucket array to store a certain minimum - // number of entries and returns its effective capacity. - static void determineCapacity(size_t minimumCapacity, float loadFactor, - size_t* __restrict__ outBucketCount, size_t* __restrict__ outCapacity); - - // Trim a hash code to 30 bits to match what we store in the bucket's cookie. - inline static hash_t trimHash(hash_t hash) { - return (hash & Bucket::HASH_MASK) ^ (hash >> 30); - } - - // Returns the index of the first bucket that is in the collision chain - // for the specified hash code, given the total number of buckets. - // (Primary hash) - inline static size_t chainStart(hash_t hash, size_t count) { - return hash % count; - } - - // Returns the increment to add to a bucket index to seek to the next bucket - // in the collision chain for the specified hash code, given the total number of buckets. - // (Secondary hash) - inline static size_t chainIncrement(hash_t hash, size_t count) { - return ((hash >> 7) | (hash << 25)) % (count - 1) + 1; - } - - // Returns the index of the next bucket that is in the collision chain - // that is defined by the specified increment, given the total number of buckets. - inline static size_t chainSeek(size_t index, size_t increment, size_t count) { - return (index + increment) % count; - } -}; - -/* - * A BasicHashtable stores entries that are indexed by hash code in place - * within an array. The basic operations are finding entries by key, - * adding new entries and removing existing entries. - * - * This class provides a very limited set of operations with simple semantics. - * It is intended to be used as a building block to construct more complex - * and interesting data structures such as HashMap. Think very hard before - * adding anything extra to BasicHashtable, it probably belongs at a - * higher level of abstraction. - * - * TKey: The key type. - * TEntry: The entry type which is what is actually stored in the array. - * - * TKey must support the following contract: - * bool operator==(const TKey& other) const; // return true if equal - * bool operator!=(const TKey& other) const; // return true if unequal - * - * TEntry must support the following contract: - * const TKey& getKey() const; // get the key from the entry - * - * This class supports storing entries with duplicate keys. Of course, it can't - * tell them apart during removal so only the first entry will be removed. - * We do this because it means that operations like add() can't fail. - */ -template <typename TKey, typename TEntry> -class BasicHashtable : private BasicHashtableImpl { -public: - /* Creates a hashtable with the specified minimum initial capacity. - * The underlying array will be created when the first entry is added. - * - * minimumInitialCapacity: The minimum initial capacity for the hashtable. - * Default is 0. - * loadFactor: The desired load factor for the hashtable, between 0 and 1. - * Default is 0.75. - */ - BasicHashtable(size_t minimumInitialCapacity = 0, float loadFactor = 0.75f); - - /* Copies a hashtable. - * The underlying storage is shared copy-on-write. - */ - BasicHashtable(const BasicHashtable& other); - - /* Clears and destroys the hashtable. - */ - virtual ~BasicHashtable(); - - /* Making this hashtable a copy of the other hashtable. - * The underlying storage is shared copy-on-write. - * - * other: The hashtable to copy. - */ - inline BasicHashtable<TKey, TEntry>& operator =(const BasicHashtable<TKey, TEntry> & other) { - setTo(other); - return *this; - } - - /* Returns the number of entries in the hashtable. - */ - inline size_t size() const { - return mSize; - } - - /* Returns the capacity of the hashtable, which is the number of elements that can - * added to the hashtable without requiring it to be grown. - */ - inline size_t capacity() const { - return mCapacity; - } - - /* Returns the number of buckets that the hashtable has, which is the size of its - * underlying array. - */ - inline size_t bucketCount() const { - return mBucketCount; - } - - /* Returns the load factor of the hashtable. */ - inline float loadFactor() const { - return mLoadFactor; - }; - - /* Returns a const reference to the entry at the specified index. - * - * index: The index of the entry to retrieve. Must be a valid index within - * the bounds of the hashtable. - */ - inline const TEntry& entryAt(size_t index) const { - return entryFor(bucketAt(mBuckets, index)); - } - - /* Returns a non-const reference to the entry at the specified index. - * - * index: The index of the entry to edit. Must be a valid index within - * the bounds of the hashtable. - */ - inline TEntry& editEntryAt(size_t index) { - edit(); - return entryFor(bucketAt(mBuckets, index)); - } - - /* Clears the hashtable. - * All entries in the hashtable are destroyed immediately. - * If you need to do something special with the entries in the hashtable then iterate - * over them and do what you need before clearing the hashtable. - */ - inline void clear() { - BasicHashtableImpl::clear(); - } - - /* Returns the index of the next entry in the hashtable given the index of a previous entry. - * If the given index is -1, then returns the index of the first entry in the hashtable, - * if there is one, or -1 otherwise. - * If the given index is not -1, then returns the index of the next entry in the hashtable, - * in strictly increasing order, or -1 if there are none left. - * - * index: The index of the previous entry that was iterated, or -1 to begin - * iteration at the beginning of the hashtable. - */ - inline ssize_t next(ssize_t index) const { - return BasicHashtableImpl::next(index); - } - - /* Finds the index of an entry with the specified key. - * If the given index is -1, then returns the index of the first matching entry, - * otherwise returns the index of the next matching entry. - * If the hashtable contains multiple entries with keys that match the requested - * key, then the sequence of entries returned is arbitrary. - * Returns -1 if no entry was found. - * - * index: The index of the previous entry with the specified key, or -1 to - * find the first matching entry. - * hash: The hashcode of the key. - * key: The key. - */ - inline ssize_t find(ssize_t index, hash_t hash, const TKey& key) const { - return BasicHashtableImpl::find(index, hash, &key); - } - - /* Adds the entry to the hashtable. - * Returns the index of the newly added entry. - * If an entry with the same key already exists, then a duplicate entry is added. - * If the entry will not fit, then the hashtable's capacity is increased and - * its contents are rehashed. See rehash(). - * - * hash: The hashcode of the key. - * entry: The entry to add. - */ - inline size_t add(hash_t hash, const TEntry& entry) { - return BasicHashtableImpl::add(hash, &entry); - } - - /* Removes the entry with the specified index from the hashtable. - * The entry is destroyed immediately. - * The index must be valid. - * - * The hashtable is not compacted after an item is removed, so it is legal - * to continue iterating over the hashtable using next() or find(). - * - * index: The index of the entry to remove. Must be a valid index within the - * bounds of the hashtable, and it must refer to an existing entry. - */ - inline void removeAt(size_t index) { - BasicHashtableImpl::removeAt(index); - } - - /* Rehashes the contents of the hashtable. - * Grows the hashtable to at least the specified minimum capacity or the - * current number of elements, whichever is larger. - * - * Rehashing causes all entries to be copied and the entry indices may change. - * Although the hash codes are cached by the hashtable, rehashing can be an - * expensive operation and should be avoided unless the hashtable's size - * needs to be changed. - * - * Rehashing is the only way to change the capacity or load factor of the - * hashtable once it has been created. It can be used to compact the - * hashtable by choosing a minimum capacity that is smaller than the current - * capacity (such as 0). - * - * minimumCapacity: The desired minimum capacity after rehashing. - * loadFactor: The desired load factor after rehashing. - */ - inline void rehash(size_t minimumCapacity, float loadFactor) { - BasicHashtableImpl::rehash(minimumCapacity, loadFactor); - } - - /* Determines whether there is room to add another entry without rehashing. - * When this returns true, a subsequent add() operation is guaranteed to - * complete without performing a rehash. - */ - inline bool hasMoreRoom() const { - return mCapacity > mFilledBuckets; - } - -protected: - static inline const TEntry& entryFor(const Bucket& bucket) { - return reinterpret_cast<const TEntry&>(bucket.entry); - } - - static inline TEntry& entryFor(Bucket& bucket) { - return reinterpret_cast<TEntry&>(bucket.entry); - } - - virtual bool compareBucketKey(const Bucket& bucket, const void* __restrict__ key) const; - virtual void initializeBucketEntry(Bucket& bucket, const void* __restrict__ entry) const; - virtual void destroyBucketEntry(Bucket& bucket) const; - -private: - // For dumping the raw contents of a hashtable during testing. - friend class BasicHashtableTest; - inline uint32_t cookieAt(size_t index) const { - return bucketAt(mBuckets, index).cookie; - } -}; - -template <typename TKey, typename TEntry> -BasicHashtable<TKey, TEntry>::BasicHashtable(size_t minimumInitialCapacity, float loadFactor) : - BasicHashtableImpl(sizeof(TEntry), traits<TEntry>::has_trivial_dtor, - minimumInitialCapacity, loadFactor) { -} - -template <typename TKey, typename TEntry> -BasicHashtable<TKey, TEntry>::BasicHashtable(const BasicHashtable<TKey, TEntry>& other) : - BasicHashtableImpl(other) { -} - -template <typename TKey, typename TEntry> -BasicHashtable<TKey, TEntry>::~BasicHashtable() { - dispose(); -} - -template <typename TKey, typename TEntry> -bool BasicHashtable<TKey, TEntry>::compareBucketKey(const Bucket& bucket, - const void* __restrict__ key) const { - return entryFor(bucket).getKey() == *static_cast<const TKey*>(key); -} - -template <typename TKey, typename TEntry> -void BasicHashtable<TKey, TEntry>::initializeBucketEntry(Bucket& bucket, - const void* __restrict__ entry) const { - if (!traits<TEntry>::has_trivial_copy) { - new (&entryFor(bucket)) TEntry(*(static_cast<const TEntry*>(entry))); - } else { - memcpy(&entryFor(bucket), entry, sizeof(TEntry)); - } -} - -template <typename TKey, typename TEntry> -void BasicHashtable<TKey, TEntry>::destroyBucketEntry(Bucket& bucket) const { - if (!traits<TEntry>::has_trivial_dtor) { - entryFor(bucket).~TEntry(); - } -} - -}; // namespace android - -#endif // ANDROID_BASIC_HASHTABLE_H diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h deleted file mode 100644 index 19c03d1..0000000 --- a/include/utils/BitSet.h +++ /dev/null @@ -1,124 +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 UTILS_BITSET_H -#define UTILS_BITSET_H - -#include <stdint.h> -#include <utils/TypeHelpers.h> - -/* - * Contains some bit manipulation helpers. - */ - -namespace android { - -// A simple set of 32 bits that can be individually marked or cleared. -struct BitSet32 { - uint32_t value; - - inline BitSet32() : value(0) { } - explicit inline BitSet32(uint32_t value) : value(value) { } - - // Gets the value associated with a particular bit index. - static inline uint32_t valueForBit(uint32_t n) { return 0x80000000 >> n; } - - // Clears the bit set. - inline void clear() { value = 0; } - - // Returns the number of marked bits in the set. - inline uint32_t count() const { return __builtin_popcount(value); } - - // Returns true if the bit set does not contain any marked bits. - inline bool isEmpty() const { return ! value; } - - // Returns true if the bit set does not contain any unmarked bits. - inline bool isFull() const { return value == 0xffffffff; } - - // Returns true if the specified bit is marked. - inline bool hasBit(uint32_t n) const { return value & valueForBit(n); } - - // Marks the specified bit. - inline void markBit(uint32_t n) { value |= valueForBit(n); } - - // Clears the specified bit. - inline void clearBit(uint32_t n) { value &= ~ valueForBit(n); } - - // Finds the first marked bit in the set. - // Result is undefined if all bits are unmarked. - inline uint32_t firstMarkedBit() const { return __builtin_clz(value); } - - // Finds the first unmarked bit in the set. - // Result is undefined if all bits are marked. - inline uint32_t firstUnmarkedBit() const { return __builtin_clz(~ value); } - - // Finds the last marked bit in the set. - // Result is undefined if all bits are unmarked. - inline uint32_t lastMarkedBit() const { return 31 - __builtin_ctz(value); } - - // Finds the first marked bit in the set and clears it. Returns the bit index. - // Result is undefined if all bits are unmarked. - inline uint32_t clearFirstMarkedBit() { - uint32_t n = firstMarkedBit(); - clearBit(n); - return n; - } - - // Finds the first unmarked bit in the set and marks it. Returns the bit index. - // Result is undefined if all bits are marked. - inline uint32_t markFirstUnmarkedBit() { - uint32_t n = firstUnmarkedBit(); - markBit(n); - return n; - } - - // Finds the last marked bit in the set and clears it. Returns the bit index. - // Result is undefined if all bits are unmarked. - inline uint32_t clearLastMarkedBit() { - uint32_t n = lastMarkedBit(); - clearBit(n); - return n; - } - - // Gets the index of the specified bit in the set, which is the number of - // marked bits that appear before the specified bit. - inline uint32_t getIndexOfBit(uint32_t n) const { - return __builtin_popcount(value & ~(0xffffffffUL >> n)); - } - - inline bool operator== (const BitSet32& other) const { return value == other.value; } - inline bool operator!= (const BitSet32& other) const { return value != other.value; } - inline BitSet32 operator& (const BitSet32& other) const { - return BitSet32(value & other.value); - } - inline BitSet32& operator&= (const BitSet32& other) { - value &= other.value; - return *this; - } - inline BitSet32 operator| (const BitSet32& other) const { - return BitSet32(value | other.value); - } - inline BitSet32& operator|= (const BitSet32& other) { - value |= other.value; - return *this; - } -}; - -ANDROID_BASIC_TYPES_TRAITS(BitSet32) - -} // namespace android - -#endif // UTILS_BITSET_H diff --git a/include/utils/BlobCache.h b/include/utils/BlobCache.h deleted file mode 100644 index 7d621e4..0000000 --- a/include/utils/BlobCache.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - ** Copyright 2011, 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_BLOB_CACHE_H -#define ANDROID_BLOB_CACHE_H - -#include <stddef.h> - -#include <utils/Flattenable.h> -#include <utils/RefBase.h> -#include <utils/SortedVector.h> -#include <utils/threads.h> - -namespace android { - -// A BlobCache is an in-memory cache for binary key/value pairs. A BlobCache -// does NOT provide any thread-safety guarantees. -// -// The cache contents can be serialized to an in-memory buffer or mmap'd file -// and then reloaded in a subsequent execution of the program. This -// serialization is non-portable and the data should only be used by the device -// that generated it. -class BlobCache : public RefBase { - -public: - - // Create an empty blob cache. The blob cache will cache key/value pairs - // with key and value sizes less than or equal to maxKeySize and - // maxValueSize, respectively. The total combined size of ALL cache entries - // (key sizes plus value sizes) will not exceed maxTotalSize. - BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize); - - // set inserts a new binary value into the cache and associates it with the - // given binary key. If the key or value are too large for the cache then - // the cache remains unchanged. This includes the case where a different - // value was previously associated with the given key - the old value will - // remain in the cache. If the given key and value are small enough to be - // put in the cache (based on the maxKeySize, maxValueSize, and maxTotalSize - // values specified to the BlobCache constructor), then the key/value pair - // will be in the cache after set returns. Note, however, that a subsequent - // call to set may evict old key/value pairs from the cache. - // - // Preconditions: - // key != NULL - // 0 < keySize - // value != NULL - // 0 < valueSize - void set(const void* key, size_t keySize, const void* value, - size_t valueSize); - - // get retrieves from the cache the binary value associated with a given - // binary key. If the key is present in the cache then the length of the - // binary value associated with that key is returned. If the value argument - // is non-NULL and the size of the cached value is less than valueSize bytes - // then the cached value is copied into the buffer pointed to by the value - // argument. If the key is not present in the cache then 0 is returned and - // the buffer pointed to by the value argument is not modified. - // - // Note that when calling get multiple times with the same key, the later - // calls may fail, returning 0, even if earlier calls succeeded. The return - // value must be checked for each call. - // - // Preconditions: - // key != NULL - // 0 < keySize - // 0 <= valueSize - size_t get(const void* key, size_t keySize, void* value, size_t valueSize); - - - // getFlattenedSize returns the number of bytes needed to store the entire - // serialized cache. - size_t getFlattenedSize() const; - - // flatten serializes the current contents of the cache into the memory - // pointed to by 'buffer'. The serialized cache contents can later be - // loaded into a BlobCache object using the unflatten method. The contents - // of the BlobCache object will not be modified. - // - // Preconditions: - // size >= this.getFlattenedSize() - status_t flatten(void* buffer, size_t size) const; - - // unflatten replaces the contents of the cache with the serialized cache - // contents in the memory pointed to by 'buffer'. The previous contents of - // the BlobCache will be evicted from the cache. If an error occurs while - // unflattening the serialized cache contents then the BlobCache will be - // left in an empty state. - // - status_t unflatten(void const* buffer, size_t size); - -private: - // Copying is disallowed. - BlobCache(const BlobCache&); - void operator=(const BlobCache&); - - // A random function helper to get around MinGW not having nrand48() - long int blob_random(); - - // clean evicts a randomly chosen set of entries from the cache such that - // the total size of all remaining entries is less than mMaxTotalSize/2. - void clean(); - - // isCleanable returns true if the cache is full enough for the clean method - // to have some effect, and false otherwise. - bool isCleanable() const; - - // A Blob is an immutable sized unstructured data blob. - class Blob : public RefBase { - public: - Blob(const void* data, size_t size, bool copyData); - ~Blob(); - - bool operator<(const Blob& rhs) const; - - const void* getData() const; - size_t getSize() const; - - private: - // Copying is not allowed. - Blob(const Blob&); - void operator=(const Blob&); - - // mData points to the buffer containing the blob data. - const void* mData; - - // mSize is the size of the blob data in bytes. - size_t mSize; - - // mOwnsData indicates whether or not this Blob object should free the - // memory pointed to by mData when the Blob gets destructed. - bool mOwnsData; - }; - - // A CacheEntry is a single key/value pair in the cache. - class CacheEntry { - public: - CacheEntry(); - CacheEntry(const sp<Blob>& key, const sp<Blob>& value); - CacheEntry(const CacheEntry& ce); - - bool operator<(const CacheEntry& rhs) const; - const CacheEntry& operator=(const CacheEntry&); - - sp<Blob> getKey() const; - sp<Blob> getValue() const; - - void setValue(const sp<Blob>& value); - - private: - - // mKey is the key that identifies the cache entry. - sp<Blob> mKey; - - // mValue is the cached data associated with the key. - sp<Blob> mValue; - }; - - // A Header is the header for the entire BlobCache serialization format. No - // need to make this portable, so we simply write the struct out. - struct Header { - // mMagicNumber is the magic number that identifies the data as - // serialized BlobCache contents. It must always contain 'Blb$'. - uint32_t mMagicNumber; - - // mBlobCacheVersion is the serialization format version. - uint32_t mBlobCacheVersion; - - // mDeviceVersion is the device-specific version of the cache. This can - // be used to invalidate the cache. - uint32_t mDeviceVersion; - - // mNumEntries is number of cache entries following the header in the - // data. - size_t mNumEntries; - }; - - // An EntryHeader is the header for a serialized cache entry. No need to - // make this portable, so we simply write the struct out. Each EntryHeader - // is followed imediately by the key data and then the value data. - // - // The beginning of each serialized EntryHeader is 4-byte aligned, so the - // number of bytes that a serialized cache entry will occupy is: - // - // ((sizeof(EntryHeader) + keySize + valueSize) + 3) & ~3 - // - struct EntryHeader { - // mKeySize is the size of the entry key in bytes. - size_t mKeySize; - - // mValueSize is the size of the entry value in bytes. - size_t mValueSize; - - // mData contains both the key and value data for the cache entry. The - // key comes first followed immediately by the value. - uint8_t mData[]; - }; - - // mMaxKeySize is the maximum key size that will be cached. Calls to - // BlobCache::set with a keySize parameter larger than mMaxKeySize will - // simply not add the key/value pair to the cache. - const size_t mMaxKeySize; - - // mMaxValueSize is the maximum value size that will be cached. Calls to - // BlobCache::set with a valueSize parameter larger than mMaxValueSize will - // simply not add the key/value pair to the cache. - const size_t mMaxValueSize; - - // mMaxTotalSize is the maximum size that all cache entries can occupy. This - // includes space for both keys and values. When a call to BlobCache::set - // would otherwise cause this limit to be exceeded, either the key/value - // pair passed to BlobCache::set will not be cached or other cache entries - // will be evicted from the cache to make room for the new entry. - const size_t mMaxTotalSize; - - // mTotalSize is the total combined size of all keys and values currently in - // the cache. - size_t mTotalSize; - - // mRandState is the pseudo-random number generator state. It is passed to - // nrand48 to generate random numbers when needed. - unsigned short mRandState[3]; - - // mCacheEntries stores all the cache entries that are resident in memory. - // Cache entries are added to it by the 'set' method. - SortedVector<CacheEntry> mCacheEntries; -}; - -} - -#endif // ANDROID_BLOB_CACHE_H diff --git a/include/utils/ByteOrder.h b/include/utils/ByteOrder.h deleted file mode 100644 index baa3a83..0000000 --- a/include/utils/ByteOrder.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2006 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 _LIBS_UTILS_BYTE_ORDER_H -#define _LIBS_UTILS_BYTE_ORDER_H - -#include <stdint.h> -#include <sys/types.h> -#ifdef HAVE_WINSOCK -#include <winsock2.h> -#else -#include <netinet/in.h> -#endif - -/* - * These macros are like the hton/ntoh byte swapping macros, - * except they allow you to swap to and from the "device" byte - * order. The device byte order is the endianness of the target - * device -- for the ARM CPUs we use today, this is little endian. - * - * Note that the byte swapping functions have not been optimized - * much; performance is currently not an issue for them since the - * intent is to allow us to avoid byte swapping on the device. - */ - -static inline uint32_t android_swap_long(uint32_t v) -{ - return (v<<24) | ((v<<8)&0x00FF0000) | ((v>>8)&0x0000FF00) | (v>>24); -} - -static inline uint16_t android_swap_short(uint16_t v) -{ - return (v<<8) | (v>>8); -} - -#define DEVICE_BYTE_ORDER LITTLE_ENDIAN - -#if BYTE_ORDER == DEVICE_BYTE_ORDER - -#define dtohl(x) (x) -#define dtohs(x) (x) -#define htodl(x) (x) -#define htods(x) (x) - -#else - -#define dtohl(x) (android_swap_long(x)) -#define dtohs(x) (android_swap_short(x)) -#define htodl(x) (android_swap_long(x)) -#define htods(x) (android_swap_short(x)) - -#endif - -#if BYTE_ORDER == LITTLE_ENDIAN -#define fromlel(x) (x) -#define fromles(x) (x) -#define tolel(x) (x) -#define toles(x) (x) -#else -#define fromlel(x) (android_swap_long(x)) -#define fromles(x) (android_swap_short(x)) -#define tolel(x) (android_swap_long(x)) -#define toles(x) (android_swap_short(x)) -#endif - -#endif // _LIBS_UTILS_BYTE_ORDER_H diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h deleted file mode 100644 index 61dc832..0000000 --- a/include/utils/CallStack.h +++ /dev/null @@ -1,76 +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_CALLSTACK_H -#define ANDROID_CALLSTACK_H - -#include <stdint.h> -#include <sys/types.h> - -#include <utils/String8.h> -#include <corkscrew/backtrace.h> - -// --------------------------------------------------------------------------- - -namespace android { - -class CallStack -{ -public: - enum { - MAX_DEPTH = 31 - }; - - CallStack(); - CallStack(const char* logtag, int32_t ignoreDepth=1, - int32_t maxDepth=MAX_DEPTH); - CallStack(const CallStack& rhs); - ~CallStack(); - - CallStack& operator = (const CallStack& rhs); - - bool operator == (const CallStack& rhs) const; - bool operator != (const CallStack& rhs) const; - bool operator < (const CallStack& rhs) const; - bool operator >= (const CallStack& rhs) const; - bool operator > (const CallStack& rhs) const; - bool operator <= (const CallStack& rhs) const; - - const void* operator [] (int index) const; - - void clear(); - - void update(int32_t ignoreDepth=1, int32_t maxDepth=MAX_DEPTH); - - // Dump a stack trace to the log using the supplied logtag - void dump(const char* logtag, const char* prefix = 0) const; - - // Return a string (possibly very long) containing the complete stack trace - String8 toString(const char* prefix = 0) const; - - size_t size() const { return mCount; } - -private: - size_t mCount; - backtrace_frame_t mStack[MAX_DEPTH]; -}; - -}; // namespace android - - -// --------------------------------------------------------------------------- - -#endif // ANDROID_CALLSTACK_H diff --git a/include/utils/Compat.h b/include/utils/Compat.h deleted file mode 100644 index fb7748e..0000000 --- a/include/utils/Compat.h +++ /dev/null @@ -1,65 +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> - -/* Compatibility definitions for non-Linux (i.e., BSD-based) hosts. */ -#ifndef HAVE_OFF64_T -#if _FILE_OFFSET_BITS < 64 -#error "_FILE_OFFSET_BITS < 64; large files are not supported on this platform" -#endif /* _FILE_OFFSET_BITS < 64 */ - -typedef off_t off64_t; - -static inline off64_t lseek64(int fd, off64_t offset, int whence) { - return lseek(fd, offset, whence); -} - -#ifdef HAVE_PREAD -static inline ssize_t pread64(int fd, void* buf, size_t nbytes, off64_t offset) { - return pread(fd, buf, nbytes, offset); -} -#endif - -#endif /* !HAVE_OFF64_T */ - -#if HAVE_PRINTF_ZD -# define ZD "%zd" -# define ZD_TYPE ssize_t -#else -# define ZD "%ld" -# define ZD_TYPE long -#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 - -#endif /* __LIB_UTILS_COMPAT_H */ diff --git a/include/utils/Condition.h b/include/utils/Condition.h deleted file mode 100644 index e63ba7e..0000000 --- a/include/utils/Condition.h +++ /dev/null @@ -1,147 +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 _LIBS_UTILS_CONDITION_H -#define _LIBS_UTILS_CONDITION_H - -#include <stdint.h> -#include <sys/types.h> -#include <time.h> - -#if defined(HAVE_PTHREADS) -# include <pthread.h> -#endif - -#include <utils/Errors.h> -#include <utils/Mutex.h> -#include <utils/Timers.h> - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -/* - * Condition variable class. The implementation is system-dependent. - * - * Condition variables are paired up with mutexes. Lock the mutex, - * call wait(), then either re-wait() if things aren't quite what you want, - * or unlock the mutex and continue. All threads calling wait() must - * use the same mutex for a given Condition. - */ -class Condition { -public: - enum { - PRIVATE = 0, - SHARED = 1 - }; - - enum WakeUpType { - WAKE_UP_ONE = 0, - WAKE_UP_ALL = 1 - }; - - Condition(); - Condition(int type); - ~Condition(); - // Wait on the condition variable. Lock the mutex before calling. - status_t wait(Mutex& mutex); - // same with relative timeout - status_t waitRelative(Mutex& mutex, nsecs_t reltime); - // Signal the condition variable, allowing one thread to continue. - void signal(); - // Signal the condition variable, allowing one or all threads to continue. - void signal(WakeUpType type) { - if (type == WAKE_UP_ONE) { - signal(); - } else { - broadcast(); - } - } - // Signal the condition variable, allowing all threads to continue. - void broadcast(); - -private: -#if defined(HAVE_PTHREADS) - pthread_cond_t mCond; -#else - void* mState; -#endif -}; - -// --------------------------------------------------------------------------- - -#if defined(HAVE_PTHREADS) - -inline Condition::Condition() { - pthread_cond_init(&mCond, NULL); -} -inline Condition::Condition(int type) { - if (type == SHARED) { - pthread_condattr_t attr; - pthread_condattr_init(&attr); - pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - pthread_cond_init(&mCond, &attr); - pthread_condattr_destroy(&attr); - } else { - pthread_cond_init(&mCond, NULL); - } -} -inline Condition::~Condition() { - pthread_cond_destroy(&mCond); -} -inline status_t Condition::wait(Mutex& mutex) { - return -pthread_cond_wait(&mCond, &mutex.mMutex); -} -inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) { -#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE) - struct timespec ts; - ts.tv_sec = reltime/1000000000; - ts.tv_nsec = reltime%1000000000; - return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts); -#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE - struct timespec ts; -#if defined(HAVE_POSIX_CLOCKS) - clock_gettime(CLOCK_REALTIME, &ts); -#else // HAVE_POSIX_CLOCKS - // we don't support the clocks here. - struct timeval t; - gettimeofday(&t, NULL); - ts.tv_sec = t.tv_sec; - ts.tv_nsec= t.tv_usec*1000; -#endif // HAVE_POSIX_CLOCKS - ts.tv_sec += reltime/1000000000; - ts.tv_nsec+= reltime%1000000000; - if (ts.tv_nsec >= 1000000000) { - ts.tv_nsec -= 1000000000; - ts.tv_sec += 1; - } - return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts); -#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE -} -inline void Condition::signal() { - pthread_cond_signal(&mCond); -} -inline void Condition::broadcast() { - pthread_cond_broadcast(&mCond); -} - -#endif // HAVE_PTHREADS - -// --------------------------------------------------------------------------- -}; // namespace android -// --------------------------------------------------------------------------- - -#endif // _LIBS_UTILS_CONDITON_H diff --git a/include/utils/Debug.h b/include/utils/Debug.h deleted file mode 100644 index 08893bd..0000000 --- a/include/utils/Debug.h +++ /dev/null @@ -1,48 +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_UTILS_DEBUG_H -#define ANDROID_UTILS_DEBUG_H - -#include <stdint.h> -#include <sys/types.h> - -namespace android { -// --------------------------------------------------------------------------- - -#ifdef __cplusplus -template<bool> struct CompileTimeAssert; -template<> struct CompileTimeAssert<true> {}; -#define COMPILE_TIME_ASSERT(_exp) \ - template class CompileTimeAssert< (_exp) >; -#endif -#define COMPILE_TIME_ASSERT_FUNCTION_SCOPE(_exp) \ - CompileTimeAssert<( _exp )>(); - -// --------------------------------------------------------------------------- - -#ifdef __cplusplus -template<bool C, typename LSH, typename RHS> struct CompileTimeIfElse; -template<typename LHS, typename RHS> -struct CompileTimeIfElse<true, LHS, RHS> { typedef LHS TYPE; }; -template<typename LHS, typename RHS> -struct CompileTimeIfElse<false, LHS, RHS> { typedef RHS TYPE; }; -#endif - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_UTILS_DEBUG_H diff --git a/include/utils/Endian.h b/include/utils/Endian.h deleted file mode 100644 index 19f2504..0000000 --- a/include/utils/Endian.h +++ /dev/null @@ -1,40 +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. - */ - -// -// Android endian-ness defines. -// -#ifndef _LIBS_UTILS_ENDIAN_H -#define _LIBS_UTILS_ENDIAN_H - -#if defined(HAVE_ENDIAN_H) - -#include <endian.h> - -#else /*not HAVE_ENDIAN_H*/ - -#define __BIG_ENDIAN 0x1000 -#define __LITTLE_ENDIAN 0x0001 - -#if defined(HAVE_LITTLE_ENDIAN) -# define __BYTE_ORDER __LITTLE_ENDIAN -#else -# define __BYTE_ORDER __BIG_ENDIAN -#endif - -#endif /*not HAVE_ENDIAN_H*/ - -#endif /*_LIBS_UTILS_ENDIAN_H*/ diff --git a/include/utils/Errors.h b/include/utils/Errors.h deleted file mode 100644 index 0b75b19..0000000 --- a/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 HAVE_MS_C_RUNTIME -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 = 0x80000000, - - NO_MEMORY = -ENOMEM, - INVALID_OPERATION = -ENOSYS, - BAD_VALUE = -EINVAL, - BAD_TYPE = 0x80000001, - NAME_NOT_FOUND = -ENOENT, - PERMISSION_DENIED = -EPERM, - NO_INIT = -ENODEV, - ALREADY_EXISTS = -EEXIST, - DEAD_OBJECT = -EPIPE, - FAILED_TRANSACTION = 0x80000002, - JPARKS_BROKE_IT = -EPIPE, -#if !defined(HAVE_MS_C_RUNTIME) - BAD_INDEX = -EOVERFLOW, - NOT_ENOUGH_DATA = -ENODATA, - WOULD_BLOCK = -EWOULDBLOCK, - TIMED_OUT = -ETIMEDOUT, - UNKNOWN_TRANSACTION = -EBADMSG, -#else - BAD_INDEX = -E2BIG, - NOT_ENOUGH_DATA = 0x80000003, - WOULD_BLOCK = 0x80000004, - TIMED_OUT = 0x80000005, - UNKNOWN_TRANSACTION = 0x80000006, -#endif - FDS_NOT_ALLOWED = 0x80000007, -}; - -// 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/include/utils/FileMap.h b/include/utils/FileMap.h deleted file mode 100644 index dfe6d51..0000000 --- a/include/utils/FileMap.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2006 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. - */ - -// -// Encapsulate a shared file mapping. -// -#ifndef __LIBS_FILE_MAP_H -#define __LIBS_FILE_MAP_H - -#include <sys/types.h> - -#include <utils/Compat.h> - -#ifdef HAVE_WIN32_FILEMAP -#include <windows.h> -#endif - -namespace android { - -/* - * This represents a memory-mapped file. It might be the entire file or - * only part of it. This requires a little bookkeeping because the mapping - * needs to be aligned on page boundaries, and in some cases we'd like to - * have multiple references to the mapped area without creating additional - * maps. - * - * This always uses MAP_SHARED. - * - * TODO: we should be able to create a new FileMap that is a subset of - * an existing FileMap and shares the underlying mapped pages. Requires - * completing the refcounting stuff and possibly introducing the notion - * of a FileMap hierarchy. - */ -class FileMap { -public: - FileMap(void); - - /* - * Create a new mapping on an open file. - * - * Closing the file descriptor does not unmap the pages, so we don't - * claim ownership of the fd. - * - * Returns "false" on failure. - */ - bool create(const char* origFileName, int fd, - off64_t offset, size_t length, bool readOnly); - - /* - * Return the name of the file this map came from, if known. - */ - const char* getFileName(void) const { return mFileName; } - - /* - * Get a pointer to the piece of the file we requested. - */ - void* getDataPtr(void) const { return mDataPtr; } - - /* - * Get the length we requested. - */ - size_t getDataLength(void) const { return mDataLength; } - - /* - * Get the data offset used to create this map. - */ - off64_t getDataOffset(void) const { return mDataOffset; } - - /* - * Get a "copy" of the object. - */ - FileMap* acquire(void) { mRefCount++; return this; } - - /* - * Call this when mapping is no longer needed. - */ - void release(void) { - if (--mRefCount <= 0) - delete this; - } - - /* - * This maps directly to madvise() values, but allows us to avoid - * including <sys/mman.h> everywhere. - */ - enum MapAdvice { - NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED - }; - - /* - * Apply an madvise() call to the entire file. - * - * Returns 0 on success, -1 on failure. - */ - int advise(MapAdvice advice); - -protected: - // don't delete objects; call release() - ~FileMap(void); - -private: - // these are not implemented - FileMap(const FileMap& src); - const FileMap& operator=(const FileMap& src); - - int mRefCount; // reference count - char* mFileName; // original file name, if known - void* mBasePtr; // base of mmap area; page aligned - size_t mBaseLength; // length, measured from "mBasePtr" - off64_t mDataOffset; // offset used when map was created - void* mDataPtr; // start of requested data, offset from base - size_t mDataLength; // length, measured from "mDataPtr" -#ifdef HAVE_WIN32_FILEMAP - HANDLE mFileHandle; // Win32 file handle - HANDLE mFileMapping; // Win32 file mapping handle -#endif - - static long mPageSize; -}; - -}; // namespace android - -#endif // __LIBS_FILE_MAP_H diff --git a/include/utils/Flattenable.h b/include/utils/Flattenable.h deleted file mode 100644 index c283ad7..0000000 --- a/include/utils/Flattenable.h +++ /dev/null @@ -1,195 +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 ANDROID_UTILS_FLATTENABLE_H -#define ANDROID_UTILS_FLATTENABLE_H - - -#include <stdint.h> -#include <sys/types.h> -#include <utils/Errors.h> -#include <utils/Debug.h> - -namespace android { - - -class FlattenableUtils { -public: - template<int N> - static size_t align(size_t size) { - COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) ); - return (size + (N-1)) & ~(N-1); - } - - template<int N> - static size_t align(void*& buffer) { - COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) ); - intptr_t b = intptr_t(buffer); - buffer = (void*)((intptr_t(buffer) + (N-1)) & ~(N-1)); - return size_t(intptr_t(buffer) - b); - } - - static void advance(void*& buffer, size_t& size, size_t offset) { - buffer = reinterpret_cast<void*>( intptr_t(buffer) + offset ); - size -= offset; - } - - static void advance(void const*& buffer, size_t& size, size_t offset) { - buffer = reinterpret_cast<void const*>( intptr_t(buffer) + offset ); - size -= offset; - } - - // write a POD structure - template<typename T> - static void write(void*& buffer, size_t& size, const T& value) { - *static_cast<T*>(buffer) = value; - advance(buffer, size, sizeof(T)); - } - - // read a POD structure - template<typename T> - static void read(void const*& buffer, size_t& size, T& value) { - value = *static_cast<T const*>(buffer); - advance(buffer, size, sizeof(T)); - } -}; - - -/* - * The Flattenable protocol allows an object to serialize itself out - * to a byte-buffer and an array of file descriptors. - * Flattenable objects must implement this protocol. - */ - -template <typename T> -class Flattenable { -public: - // size in bytes of the flattened object - inline size_t getFlattenedSize() const; - - // number of file descriptors to flatten - inline size_t getFdCount() const; - - // flattens the object into buffer. - // size should be at least of getFlattenedSize() - // file descriptors are written in the fds[] array but ownership is - // not transfered (ie: they must be dupped by the caller of - // flatten() if needed). - inline status_t flatten(void*& buffer, size_t& size, - int*& fds, size_t& count) const; - - // unflattens the object from buffer. - // size should be equal to the value of getFlattenedSize() when the - // object was flattened. - // unflattened file descriptors are found in the fds[] array and - // don't need to be dupped(). ie: the caller of unflatten doesn't - // keep ownership. If a fd is not retained by unflatten() it must be - // explicitly closed. - inline status_t unflatten(void const*& buffer, size_t& size, - int const*& fds, size_t& count); -}; - -template<typename T> -inline size_t Flattenable<T>::getFlattenedSize() const { - return static_cast<T const*>(this)->T::getFlattenedSize(); -} -template<typename T> -inline size_t Flattenable<T>::getFdCount() const { - return static_cast<T const*>(this)->T::getFdCount(); -} -template<typename T> -inline status_t Flattenable<T>::flatten( - void*& buffer, size_t& size, int*& fds, size_t& count) const { - return static_cast<T const*>(this)->T::flatten(buffer, size, fds, count); -} -template<typename T> -inline status_t Flattenable<T>::unflatten( - void const*& buffer, size_t& size, int const*& fds, size_t& count) { - return static_cast<T*>(this)->T::unflatten(buffer, size, fds, count); -} - -/* - * LightFlattenable is a protocol allowing object to serialize themselves out - * to a byte-buffer. Because it doesn't handle file-descriptors, - * LightFlattenable is usually more size efficient than Flattenable. - * LightFlattenable objects must implement this protocol. - */ -template <typename T> -class LightFlattenable { -public: - // returns whether this object always flatten into the same size. - // for efficiency, this should always be inline. - inline bool isFixedSize() const; - - // returns size in bytes of the flattened object. must be a constant. - inline size_t getFlattenedSize() const; - - // flattens the object into buffer. - inline status_t flatten(void* buffer, size_t size) const; - - // unflattens the object from buffer of given size. - inline status_t unflatten(void const* buffer, size_t size); -}; - -template <typename T> -inline bool LightFlattenable<T>::isFixedSize() const { - return static_cast<T const*>(this)->T::isFixedSize(); -} -template <typename T> -inline size_t LightFlattenable<T>::getFlattenedSize() const { - return static_cast<T const*>(this)->T::getFlattenedSize(); -} -template <typename T> -inline status_t LightFlattenable<T>::flatten(void* buffer, size_t size) const { - return static_cast<T const*>(this)->T::flatten(buffer, size); -} -template <typename T> -inline status_t LightFlattenable<T>::unflatten(void const* buffer, size_t size) { - return static_cast<T*>(this)->T::unflatten(buffer, size); -} - -/* - * LightFlattenablePod is an implementation of the LightFlattenable protocol - * for POD (plain-old-data) objects. - * Simply derive from LightFlattenablePod<Foo> to make Foo flattenable; no - * need to implement any methods; obviously Foo must be a POD structure. - */ -template <typename T> -class LightFlattenablePod : public LightFlattenable<T> { -public: - inline bool isFixedSize() const { - return true; - } - - inline size_t getFlattenedSize() const { - return sizeof(T); - } - inline status_t flatten(void* buffer, size_t size) const { - if (size < sizeof(T)) return NO_MEMORY; - *reinterpret_cast<T*>(buffer) = *static_cast<T const*>(this); - return NO_ERROR; - } - inline status_t unflatten(void const* buffer, size_t) { - *static_cast<T*>(this) = *reinterpret_cast<T const*>(buffer); - return NO_ERROR; - } -}; - - -}; // namespace android - - -#endif /* ANDROID_UTILS_FLATTENABLE_H */ diff --git a/include/utils/Functor.h b/include/utils/Functor.h deleted file mode 100644 index e24ded4..0000000 --- a/include/utils/Functor.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2011 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_FUNCTOR_H -#define ANDROID_FUNCTOR_H - -#include <utils/Errors.h> - -namespace android { - -class Functor { -public: - Functor() {} - virtual ~Functor() {} - virtual status_t operator ()(int what, void* data) { return NO_ERROR; } -}; - -}; // namespace android - -#endif // ANDROID_FUNCTOR_H diff --git a/include/utils/JenkinsHash.h b/include/utils/JenkinsHash.h deleted file mode 100644 index 7da5dbd..0000000 --- a/include/utils/JenkinsHash.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -/* Implementation of Jenkins one-at-a-time hash function. These choices are - * optimized for code size and portability, rather than raw speed. But speed - * should still be quite good. - **/ - -#ifndef ANDROID_JENKINS_HASH_H -#define ANDROID_JENKINS_HASH_H - -#include <utils/TypeHelpers.h> - -namespace android { - -/* The Jenkins hash of a sequence of 32 bit words A, B, C is: - * Whiten(Mix(Mix(Mix(0, A), B), C)) */ - -inline uint32_t JenkinsHashMix(uint32_t hash, uint32_t data) { - hash += data; - hash += (hash << 10); - hash ^= (hash >> 6); - return hash; -} - -hash_t JenkinsHashWhiten(uint32_t hash); - -/* Helpful utility functions for hashing data in 32 bit chunks */ -uint32_t JenkinsHashMixBytes(uint32_t hash, const uint8_t* bytes, size_t size); - -uint32_t JenkinsHashMixShorts(uint32_t hash, const uint16_t* shorts, size_t size); - -} - -#endif // ANDROID_JENKINS_HASH_H diff --git a/include/utils/KeyedVector.h b/include/utils/KeyedVector.h deleted file mode 100644 index c4faae0..0000000 --- a/include/utils/KeyedVector.h +++ /dev/null @@ -1,224 +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_KEYED_VECTOR_H -#define ANDROID_KEYED_VECTOR_H - -#include <assert.h> -#include <stdint.h> -#include <sys/types.h> - -#include <cutils/log.h> - -#include <utils/SortedVector.h> -#include <utils/TypeHelpers.h> -#include <utils/Errors.h> - -// --------------------------------------------------------------------------- - -namespace android { - -template <typename KEY, typename VALUE> -class KeyedVector -{ -public: - typedef KEY key_type; - typedef VALUE value_type; - - inline KeyedVector(); - - /* - * empty the vector - */ - - inline void clear() { mVector.clear(); } - - /*! - * vector stats - */ - - //! returns number of items in the vector - inline size_t size() const { return mVector.size(); } - //! returns whether or not the vector is empty - inline bool isEmpty() const { return mVector.isEmpty(); } - //! returns how many items can be stored without reallocating the backing store - inline size_t capacity() const { return mVector.capacity(); } - //! sets the capacity. capacity can never be reduced less than size() - inline ssize_t setCapacity(size_t size) { return mVector.setCapacity(size); } - - // returns true if the arguments is known to be identical to this vector - inline bool isIdenticalTo(const KeyedVector& rhs) const; - - /*! - * accessors - */ - const VALUE& valueFor(const KEY& key) const; - const VALUE& valueAt(size_t index) const; - const KEY& keyAt(size_t index) const; - ssize_t indexOfKey(const KEY& key) const; - const VALUE& operator[] (size_t index) const; - - /*! - * modifying the array - */ - - VALUE& editValueFor(const KEY& key); - VALUE& editValueAt(size_t index); - - /*! - * add/insert/replace items - */ - - ssize_t add(const KEY& key, const VALUE& item); - ssize_t replaceValueFor(const KEY& key, const VALUE& item); - ssize_t replaceValueAt(size_t index, const VALUE& item); - - /*! - * remove items - */ - - ssize_t removeItem(const KEY& key); - ssize_t removeItemsAt(size_t index, size_t count = 1); - -private: - SortedVector< key_value_pair_t<KEY, VALUE> > mVector; -}; - -// KeyedVector<KEY, VALUE> can be trivially moved using memcpy() because its -// underlying SortedVector can be trivially moved. -template<typename KEY, typename VALUE> struct trait_trivial_move<KeyedVector<KEY, VALUE> > { - enum { value = trait_trivial_move<SortedVector< key_value_pair_t<KEY, VALUE> > >::value }; -}; - - -// --------------------------------------------------------------------------- - -/** - * Variation of KeyedVector that holds a default value to return when - * valueFor() is called with a key that doesn't exist. - */ -template <typename KEY, typename VALUE> -class DefaultKeyedVector : public KeyedVector<KEY, VALUE> -{ -public: - inline DefaultKeyedVector(const VALUE& defValue = VALUE()); - const VALUE& valueFor(const KEY& key) const; - -private: - VALUE mDefault; -}; - -// --------------------------------------------------------------------------- - -template<typename KEY, typename VALUE> inline -KeyedVector<KEY,VALUE>::KeyedVector() -{ -} - -template<typename KEY, typename VALUE> inline -bool KeyedVector<KEY,VALUE>::isIdenticalTo(const KeyedVector<KEY,VALUE>& rhs) const { - return mVector.array() == rhs.mVector.array(); -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY,VALUE>::indexOfKey(const KEY& key) const { - return mVector.indexOf( key_value_pair_t<KEY,VALUE>(key) ); -} - -template<typename KEY, typename VALUE> inline -const VALUE& KeyedVector<KEY,VALUE>::valueFor(const KEY& key) const { - ssize_t i = this->indexOfKey(key); - LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__); - return mVector.itemAt(i).value; -} - -template<typename KEY, typename VALUE> inline -const VALUE& KeyedVector<KEY,VALUE>::valueAt(size_t index) const { - return mVector.itemAt(index).value; -} - -template<typename KEY, typename VALUE> inline -const VALUE& KeyedVector<KEY,VALUE>::operator[] (size_t index) const { - return valueAt(index); -} - -template<typename KEY, typename VALUE> inline -const KEY& KeyedVector<KEY,VALUE>::keyAt(size_t index) const { - return mVector.itemAt(index).key; -} - -template<typename KEY, typename VALUE> inline -VALUE& KeyedVector<KEY,VALUE>::editValueFor(const KEY& key) { - ssize_t i = this->indexOfKey(key); - LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__); - return mVector.editItemAt(i).value; -} - -template<typename KEY, typename VALUE> inline -VALUE& KeyedVector<KEY,VALUE>::editValueAt(size_t index) { - return mVector.editItemAt(index).value; -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY,VALUE>::add(const KEY& key, const VALUE& value) { - return mVector.add( key_value_pair_t<KEY,VALUE>(key, value) ); -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY,VALUE>::replaceValueFor(const KEY& key, const VALUE& value) { - key_value_pair_t<KEY,VALUE> pair(key, value); - mVector.remove(pair); - return mVector.add(pair); -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY,VALUE>::replaceValueAt(size_t index, const VALUE& item) { - if (index<size()) { - mVector.editItemAt(index).value = item; - return index; - } - return BAD_INDEX; -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY,VALUE>::removeItem(const KEY& key) { - return mVector.remove(key_value_pair_t<KEY,VALUE>(key)); -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY, VALUE>::removeItemsAt(size_t index, size_t count) { - return mVector.removeItemsAt(index, count); -} - -// --------------------------------------------------------------------------- - -template<typename KEY, typename VALUE> inline -DefaultKeyedVector<KEY,VALUE>::DefaultKeyedVector(const VALUE& defValue) - : mDefault(defValue) -{ -} - -template<typename KEY, typename VALUE> inline -const VALUE& DefaultKeyedVector<KEY,VALUE>::valueFor(const KEY& key) const { - ssize_t i = this->indexOfKey(key); - return i >= 0 ? KeyedVector<KEY,VALUE>::valueAt(i) : mDefault; -} - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_KEYED_VECTOR_H diff --git a/include/utils/LinearAllocator.h b/include/utils/LinearAllocator.h deleted file mode 100644 index 4772bc8..0000000 --- a/include/utils/LinearAllocator.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2012, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ANDROID_LINEARALLOCATOR_H -#define ANDROID_LINEARALLOCATOR_H - -#include <stddef.h> - -namespace android { - -/** - * A memory manager that internally allocates multi-kbyte buffers for placing objects in. It avoids - * the overhead of malloc when many objects are allocated. It is most useful when creating many - * small objects with a similar lifetime, and doesn't add significant overhead for large - * allocations. - */ -class LinearAllocator { -public: - LinearAllocator(); - ~LinearAllocator(); - - /** - * Reserves and returns a region of memory of at least size 'size', aligning as needed. - * Typically this is used in an object's overridden new() method or as a replacement for malloc. - * - * The lifetime of the returned buffers is tied to that of the LinearAllocator. If calling - * delete() on an object stored in a buffer is needed, it should be overridden to use - * rewindIfLastAlloc() - */ - void* alloc(size_t size); - - /** - * Attempt to deallocate the given buffer, with the LinearAllocator attempting to rewind its - * state if possible. No destructors are called. - */ - void rewindIfLastAlloc(void* ptr, size_t allocSize); - - /** - * Dump memory usage statistics to the log (allocated and wasted space) - */ - void dumpMemoryStats(const char* prefix = ""); - - /** - * The number of bytes used for buffers allocated in the LinearAllocator (does not count space - * wasted) - */ - size_t usedSize() const { return mTotalAllocated - mWastedSpace; } - -private: - LinearAllocator(const LinearAllocator& other); - - class Page; - - Page* newPage(size_t pageSize); - bool fitsInCurrentPage(size_t size); - void ensureNext(size_t size); - void* start(Page *p); - void* end(Page* p); - - size_t mPageSize; - size_t mMaxAllocSize; - void* mNext; - Page* mCurrentPage; - Page* mPages; - - // Memory usage tracking - size_t mTotalAllocated; - size_t mWastedSpace; - size_t mPageCount; - size_t mDedicatedPageCount; -}; - -}; // namespace android - -#endif // ANDROID_LINEARALLOCATOR_H diff --git a/include/utils/LinearTransform.h b/include/utils/LinearTransform.h deleted file mode 100644 index 04cb355..0000000 --- a/include/utils/LinearTransform.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2011 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 _LIBS_UTILS_LINEAR_TRANSFORM_H -#define _LIBS_UTILS_LINEAR_TRANSFORM_H - -#include <stdint.h> - -namespace android { - -// LinearTransform defines a structure which hold the definition of a -// transformation from single dimensional coordinate system A into coordinate -// system B (and back again). Values in A and in B are 64 bit, the linear -// scale factor is expressed as a rational number using two 32 bit values. -// -// Specifically, let -// f(a) = b -// F(b) = f^-1(b) = a -// then -// -// f(a) = (((a - a_zero) * a_to_b_numer) / a_to_b_denom) + b_zero; -// -// and -// -// F(b) = (((b - b_zero) * a_to_b_denom) / a_to_b_numer) + a_zero; -// -struct LinearTransform { - int64_t a_zero; - int64_t b_zero; - int32_t a_to_b_numer; - uint32_t a_to_b_denom; - - // Transform from A->B - // Returns true on success, or false in the case of a singularity or an - // overflow. - bool doForwardTransform(int64_t a_in, int64_t* b_out) const; - - // Transform from B->A - // Returns true on success, or false in the case of a singularity or an - // overflow. - bool doReverseTransform(int64_t b_in, int64_t* a_out) const; - - // Helpers which will reduce the fraction N/D using Euclid's method. - template <class T> static void reduce(T* N, T* D); - static void reduce(int32_t* N, uint32_t* D); -}; - - -} - -#endif // _LIBS_UTILS_LINEAR_TRANSFORM_H diff --git a/include/utils/List.h b/include/utils/List.h deleted file mode 100644 index 403cd7f..0000000 --- a/include/utils/List.h +++ /dev/null @@ -1,332 +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. - */ - -// -// Templated list class. Normally we'd use STL, but we don't have that. -// This class mimics STL's interfaces. -// -// Objects are copied into the list with the '=' operator or with copy- -// construction, so if the compiler's auto-generated versions won't work for -// you, define your own. -// -// The only class you want to use from here is "List". -// -#ifndef _LIBS_UTILS_LIST_H -#define _LIBS_UTILS_LIST_H - -#include <stddef.h> -#include <stdint.h> - -namespace android { - -/* - * Doubly-linked list. Instantiate with "List<MyClass> myList". - * - * Objects added to the list are copied using the assignment operator, - * so this must be defined. - */ -template<typename T> -class List -{ -protected: - /* - * One element in the list. - */ - class _Node { - public: - explicit _Node(const T& val) : mVal(val) {} - ~_Node() {} - inline T& getRef() { return mVal; } - inline const T& getRef() const { return mVal; } - inline _Node* getPrev() const { return mpPrev; } - inline _Node* getNext() const { return mpNext; } - inline void setVal(const T& val) { mVal = val; } - inline void setPrev(_Node* ptr) { mpPrev = ptr; } - inline void setNext(_Node* ptr) { mpNext = ptr; } - private: - friend class List; - friend class _ListIterator; - T mVal; - _Node* mpPrev; - _Node* mpNext; - }; - - /* - * Iterator for walking through the list. - */ - - template <typename TYPE> - struct CONST_ITERATOR { - typedef _Node const * NodePtr; - typedef const TYPE Type; - }; - - template <typename TYPE> - struct NON_CONST_ITERATOR { - typedef _Node* NodePtr; - typedef TYPE Type; - }; - - template< - typename U, - template <class> class Constness - > - class _ListIterator { - typedef _ListIterator<U, Constness> _Iter; - typedef typename Constness<U>::NodePtr _NodePtr; - typedef typename Constness<U>::Type _Type; - - explicit _ListIterator(_NodePtr ptr) : mpNode(ptr) {} - - public: - _ListIterator() {} - _ListIterator(const _Iter& rhs) : mpNode(rhs.mpNode) {} - ~_ListIterator() {} - - // this will handle conversions from iterator to const_iterator - // (and also all convertible iterators) - // Here, in this implementation, the iterators can be converted - // if the nodes can be converted - template<typename V> explicit - _ListIterator(const V& rhs) : mpNode(rhs.mpNode) {} - - - /* - * Dereference operator. Used to get at the juicy insides. - */ - _Type& operator*() const { return mpNode->getRef(); } - _Type* operator->() const { return &(mpNode->getRef()); } - - /* - * Iterator comparison. - */ - inline bool operator==(const _Iter& right) const { - return mpNode == right.mpNode; } - - inline bool operator!=(const _Iter& right) const { - return mpNode != right.mpNode; } - - /* - * handle comparisons between iterator and const_iterator - */ - template<typename OTHER> - inline bool operator==(const OTHER& right) const { - return mpNode == right.mpNode; } - - template<typename OTHER> - inline bool operator!=(const OTHER& right) const { - return mpNode != right.mpNode; } - - /* - * Incr/decr, used to move through the list. - */ - inline _Iter& operator++() { // pre-increment - mpNode = mpNode->getNext(); - return *this; - } - const _Iter operator++(int) { // post-increment - _Iter tmp(*this); - mpNode = mpNode->getNext(); - return tmp; - } - inline _Iter& operator--() { // pre-increment - mpNode = mpNode->getPrev(); - return *this; - } - const _Iter operator--(int) { // post-increment - _Iter tmp(*this); - mpNode = mpNode->getPrev(); - return tmp; - } - - inline _NodePtr getNode() const { return mpNode; } - - _NodePtr mpNode; /* should be private, but older gcc fails */ - private: - friend class List; - }; - -public: - List() { - prep(); - } - List(const List<T>& src) { // copy-constructor - prep(); - insert(begin(), src.begin(), src.end()); - } - virtual ~List() { - clear(); - delete[] (unsigned char*) mpMiddle; - } - - typedef _ListIterator<T, NON_CONST_ITERATOR> iterator; - typedef _ListIterator<T, CONST_ITERATOR> const_iterator; - - List<T>& operator=(const List<T>& right); - - /* returns true if the list is empty */ - inline bool empty() const { return mpMiddle->getNext() == mpMiddle; } - - /* return #of elements in list */ - size_t size() const { - return size_t(distance(begin(), end())); - } - - /* - * Return the first element or one past the last element. The - * _Node* we're returning is converted to an "iterator" by a - * constructor in _ListIterator. - */ - inline iterator begin() { - return iterator(mpMiddle->getNext()); - } - inline const_iterator begin() const { - return const_iterator(const_cast<_Node const*>(mpMiddle->getNext())); - } - inline iterator end() { - return iterator(mpMiddle); - } - inline const_iterator end() const { - return const_iterator(const_cast<_Node const*>(mpMiddle)); - } - - /* add the object to the head or tail of the list */ - void push_front(const T& val) { insert(begin(), val); } - void push_back(const T& val) { insert(end(), val); } - - /* insert before the current node; returns iterator at new node */ - iterator insert(iterator posn, const T& val) - { - _Node* newNode = new _Node(val); // alloc & copy-construct - newNode->setNext(posn.getNode()); - newNode->setPrev(posn.getNode()->getPrev()); - posn.getNode()->getPrev()->setNext(newNode); - posn.getNode()->setPrev(newNode); - return iterator(newNode); - } - - /* insert a range of elements before the current node */ - void insert(iterator posn, const_iterator first, const_iterator last) { - for ( ; first != last; ++first) - insert(posn, *first); - } - - /* remove one entry; returns iterator at next node */ - iterator erase(iterator posn) { - _Node* pNext = posn.getNode()->getNext(); - _Node* pPrev = posn.getNode()->getPrev(); - pPrev->setNext(pNext); - pNext->setPrev(pPrev); - delete posn.getNode(); - return iterator(pNext); - } - - /* remove a range of elements */ - iterator erase(iterator first, iterator last) { - while (first != last) - erase(first++); // don't erase than incr later! - return iterator(last); - } - - /* remove all contents of the list */ - void clear() { - _Node* pCurrent = mpMiddle->getNext(); - _Node* pNext; - - while (pCurrent != mpMiddle) { - pNext = pCurrent->getNext(); - delete pCurrent; - pCurrent = pNext; - } - mpMiddle->setPrev(mpMiddle); - mpMiddle->setNext(mpMiddle); - } - - /* - * Measure the distance between two iterators. On exist, "first" - * will be equal to "last". The iterators must refer to the same - * list. - * - * FIXME: This is actually a generic iterator function. It should be a - * template function at the top-level with specializations for things like - * vector<>, which can just do pointer math). Here we limit it to - * _ListIterator of the same type but different constness. - */ - template< - typename U, - template <class> class CL, - template <class> class CR - > - ptrdiff_t distance( - _ListIterator<U, CL> first, _ListIterator<U, CR> last) const - { - ptrdiff_t count = 0; - while (first != last) { - ++first; - ++count; - } - return count; - } - -private: - /* - * I want a _Node but don't need it to hold valid data. More - * to the point, I don't want T's constructor to fire, since it - * might have side-effects or require arguments. So, we do this - * slightly uncouth storage alloc. - */ - void prep() { - mpMiddle = (_Node*) new unsigned char[sizeof(_Node)]; - mpMiddle->setPrev(mpMiddle); - mpMiddle->setNext(mpMiddle); - } - - /* - * This node plays the role of "pointer to head" and "pointer to tail". - * It sits in the middle of a circular list of nodes. The iterator - * runs around the circle until it encounters this one. - */ - _Node* mpMiddle; -}; - -/* - * Assignment operator. - * - * The simplest way to do this would be to clear out the target list and - * fill it with the source. However, we can speed things along by - * re-using existing elements. - */ -template<class T> -List<T>& List<T>::operator=(const List<T>& right) -{ - if (this == &right) - return *this; // self-assignment - iterator firstDst = begin(); - iterator lastDst = end(); - const_iterator firstSrc = right.begin(); - const_iterator lastSrc = right.end(); - while (firstSrc != lastSrc && firstDst != lastDst) - *firstDst++ = *firstSrc++; - if (firstSrc == lastSrc) // ran out of elements in source? - erase(firstDst, lastDst); // yes, erase any extras - else - insert(lastDst, firstSrc, lastSrc); // copy remaining over - return *this; -} - -}; // namespace android - -#endif // _LIBS_UTILS_LIST_H diff --git a/include/utils/Log.h b/include/utils/Log.h deleted file mode 100644 index 4259c86..0000000 --- a/include/utils/Log.h +++ /dev/null @@ -1,71 +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. - */ - -// -// C/C++ logging functions. See the logging documentation for API details. -// -// We'd like these to be available from C code (in case we import some from -// somewhere), so this has a C interface. -// -// The output will be correct when the log file is shared between multiple -// threads and/or multiple processes so long as the operating system -// supports O_APPEND. These calls have mutex-protected data structures -// and so are NOT reentrant. Do not use LOG in a signal handler. -// -#ifndef _LIBS_UTILS_LOG_H -#define _LIBS_UTILS_LOG_H - -#include <cutils/log.h> -#include <sys/types.h> - -#ifdef __cplusplus - -namespace android { - -/* - * A very simple utility that yells in the log when an operation takes too long. - */ -class LogIfSlow { -public: - LogIfSlow(const char* tag, android_LogPriority priority, - int timeoutMillis, const char* message); - ~LogIfSlow(); - -private: - const char* const mTag; - const android_LogPriority mPriority; - const int mTimeoutMillis; - const char* const mMessage; - const int64_t mStart; -}; - -/* - * Writes the specified debug log message if this block takes longer than the - * specified number of milliseconds to run. Includes the time actually taken. - * - * { - * ALOGD_IF_SLOW(50, "Excessive delay doing something."); - * doSomething(); - * } - */ -#define ALOGD_IF_SLOW(timeoutMillis, message) \ - android::LogIfSlow _logIfSlow(LOG_TAG, ANDROID_LOG_DEBUG, timeoutMillis, message); - -} // namespace android - -#endif // __cplusplus - -#endif // _LIBS_UTILS_LOG_H diff --git a/include/utils/Looper.h b/include/utils/Looper.h deleted file mode 100644 index 2e0651a..0000000 --- a/include/utils/Looper.h +++ /dev/null @@ -1,388 +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 UTILS_LOOPER_H -#define UTILS_LOOPER_H - -#include <utils/threads.h> -#include <utils/RefBase.h> -#include <utils/KeyedVector.h> -#include <utils/Timers.h> - -#include <android/looper.h> - -#include <sys/epoll.h> - -/* - * Declare a concrete type for the NDK's looper forward declaration. - */ -struct ALooper { -}; - -namespace android { - -/** - * A message that can be posted to a Looper. - */ -struct Message { - Message() : what(0) { } - Message(int what) : what(what) { } - - /* The message type. (interpretation is left up to the handler) */ - int what; -}; - - -/** - * Interface for a Looper message handler. - * - * The Looper holds a strong reference to the message handler whenever it has - * a message to deliver to it. Make sure to call Looper::removeMessages - * to remove any pending messages destined for the handler so that the handler - * can be destroyed. - */ -class MessageHandler : public virtual RefBase { -protected: - virtual ~MessageHandler() { } - -public: - /** - * Handles a message. - */ - virtual void handleMessage(const Message& message) = 0; -}; - - -/** - * A simple proxy that holds a weak reference to a message handler. - */ -class WeakMessageHandler : public MessageHandler { -protected: - virtual ~WeakMessageHandler(); - -public: - WeakMessageHandler(const wp<MessageHandler>& handler); - virtual void handleMessage(const Message& message); - -private: - wp<MessageHandler> mHandler; -}; - - -/** - * A looper callback. - */ -class LooperCallback : public virtual RefBase { -protected: - virtual ~LooperCallback() { } - -public: - /** - * Handles a poll event for the given file descriptor. - * It is given the file descriptor it is associated with, - * a bitmask of the poll events that were triggered (typically ALOOPER_EVENT_INPUT), - * and the data pointer that was originally supplied. - * - * Implementations should return 1 to continue receiving callbacks, or 0 - * to have this file descriptor and callback unregistered from the looper. - */ - virtual int handleEvent(int fd, int events, void* data) = 0; -}; - - -/** - * Wraps a ALooper_callbackFunc function pointer. - */ -class SimpleLooperCallback : public LooperCallback { -protected: - virtual ~SimpleLooperCallback(); - -public: - SimpleLooperCallback(ALooper_callbackFunc callback); - virtual int handleEvent(int fd, int events, void* data); - -private: - ALooper_callbackFunc mCallback; -}; - - -/** - * A polling loop that supports monitoring file descriptor events, optionally - * using callbacks. The implementation uses epoll() internally. - * - * A looper can be associated with a thread although there is no requirement that it must be. - */ -class Looper : public ALooper, public RefBase { -protected: - virtual ~Looper(); - -public: - /** - * Creates a looper. - * - * If allowNonCallbaks is true, the looper will allow file descriptors to be - * registered without associated callbacks. This assumes that the caller of - * pollOnce() is prepared to handle callback-less events itself. - */ - Looper(bool allowNonCallbacks); - - /** - * Returns whether this looper instance allows the registration of file descriptors - * using identifiers instead of callbacks. - */ - bool getAllowNonCallbacks() const; - - /** - * Waits for events to be available, with optional timeout in milliseconds. - * Invokes callbacks for all file descriptors on which an event occurred. - * - * If the timeout is zero, returns immediately without blocking. - * If the timeout is negative, waits indefinitely until an event appears. - * - * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before - * the timeout expired and no callbacks were invoked and no other file - * descriptors were ready. - * - * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked. - * - * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given - * timeout expired. - * - * Returns ALOOPER_POLL_ERROR if an error occurred. - * - * Returns a value >= 0 containing an identifier if its file descriptor has data - * and it has no callback function (requiring the caller here to handle it). - * In this (and only this) case outFd, outEvents and outData will contain the poll - * events and data associated with the fd, otherwise they will be set to NULL. - * - * This method does not return until it has finished invoking the appropriate callbacks - * for all file descriptors that were signalled. - */ - int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData); - inline int pollOnce(int timeoutMillis) { - return pollOnce(timeoutMillis, NULL, NULL, NULL); - } - - /** - * Like pollOnce(), but performs all pending callbacks until all - * data has been consumed or a file descriptor is available with no callback. - * This function will never return ALOOPER_POLL_CALLBACK. - */ - int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData); - inline int pollAll(int timeoutMillis) { - return pollAll(timeoutMillis, NULL, NULL, NULL); - } - - /** - * Wakes the poll asynchronously. - * - * This method can be called on any thread. - * This method returns immediately. - */ - void wake(); - - /** - * Adds a new file descriptor to be polled by the looper. - * If the same file descriptor was previously added, it is replaced. - * - * "fd" is the file descriptor to be added. - * "ident" is an identifier for this event, which is returned from pollOnce(). - * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback. - * "events" are the poll events to wake up on. Typically this is ALOOPER_EVENT_INPUT. - * "callback" is the function to call when there is an event on the file descriptor. - * "data" is a private data pointer to supply to the callback. - * - * There are two main uses of this function: - * - * (1) If "callback" is non-NULL, then this function will be called when there is - * data on the file descriptor. It should execute any events it has pending, - * appropriately reading from the file descriptor. The 'ident' is ignored in this case. - * - * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce - * when its file descriptor has data available, requiring the caller to take - * care of processing it. - * - * Returns 1 if the file descriptor was added, 0 if the arguments were invalid. - * - * This method can be called on any thread. - * This method may block briefly if it needs to wake the poll. - * - * The callback may either be specified as a bare function pointer or as a smart - * pointer callback object. The smart pointer should be preferred because it is - * easier to avoid races when the callback is removed from a different thread. - * See removeFd() for details. - */ - int addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data); - int addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data); - - /** - * Removes a previously added file descriptor from the looper. - * - * When this method returns, it is safe to close the file descriptor since the looper - * will no longer have a reference to it. However, it is possible for the callback to - * already be running or for it to run one last time if the file descriptor was already - * signalled. Calling code is responsible for ensuring that this case is safely handled. - * For example, if the callback takes care of removing itself during its own execution either - * by returning 0 or by calling this method, then it can be guaranteed to not be invoked - * again at any later time unless registered anew. - * - * A simple way to avoid this problem is to use the version of addFd() that takes - * a sp<LooperCallback> instead of a bare function pointer. The LooperCallback will - * be released at the appropriate time by the Looper. - * - * Returns 1 if the file descriptor was removed, 0 if none was previously registered. - * - * This method can be called on any thread. - * This method may block briefly if it needs to wake the poll. - */ - int removeFd(int fd); - - /** - * Enqueues a message to be processed by the specified handler. - * - * The handler must not be null. - * This method can be called on any thread. - */ - void sendMessage(const sp<MessageHandler>& handler, const Message& message); - - /** - * Enqueues a message to be processed by the specified handler after all pending messages - * after the specified delay. - * - * The time delay is specified in uptime nanoseconds. - * The handler must not be null. - * This method can be called on any thread. - */ - void sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler, - const Message& message); - - /** - * Enqueues a message to be processed by the specified handler after all pending messages - * at the specified time. - * - * The time is specified in uptime nanoseconds. - * The handler must not be null. - * This method can be called on any thread. - */ - void sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler, - const Message& message); - - /** - * Removes all messages for the specified handler from the queue. - * - * The handler must not be null. - * This method can be called on any thread. - */ - void removeMessages(const sp<MessageHandler>& handler); - - /** - * Removes all messages of a particular type for the specified handler from the queue. - * - * The handler must not be null. - * This method can be called on any thread. - */ - void removeMessages(const sp<MessageHandler>& handler, int what); - - /** - * Return whether this looper's thread is currently idling -- that is, whether it - * stopped waiting for more work to do. Note that this is intrinsically racy, since - * its state can change before you get the result back. - */ - bool isIdling() const; - - /** - * Prepares a looper associated with the calling thread, and returns it. - * If the thread already has a looper, it is returned. Otherwise, a new - * one is created, associated with the thread, and returned. - * - * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0. - */ - static sp<Looper> prepare(int opts); - - /** - * Sets the given looper to be associated with the calling thread. - * If another looper is already associated with the thread, it is replaced. - * - * If "looper" is NULL, removes the currently associated looper. - */ - static void setForThread(const sp<Looper>& looper); - - /** - * Returns the looper associated with the calling thread, or NULL if - * there is not one. - */ - static sp<Looper> getForThread(); - -private: - struct Request { - int fd; - int ident; - sp<LooperCallback> callback; - void* data; - }; - - struct Response { - int events; - Request request; - }; - - struct MessageEnvelope { - MessageEnvelope() : uptime(0) { } - - MessageEnvelope(nsecs_t uptime, const sp<MessageHandler> handler, - const Message& message) : uptime(uptime), handler(handler), message(message) { - } - - nsecs_t uptime; - sp<MessageHandler> handler; - Message message; - }; - - const bool mAllowNonCallbacks; // immutable - - int mWakeReadPipeFd; // immutable - int mWakeWritePipeFd; // immutable - Mutex mLock; - - Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock - bool mSendingMessage; // guarded by mLock - - // Whether we are currently waiting for work. Not protected by a lock, - // any use of it is racy anyway. - volatile bool mIdling; - - int mEpollFd; // immutable - - // Locked list of file descriptor monitoring requests. - KeyedVector<int, Request> mRequests; // guarded by mLock - - // This state is only used privately by pollOnce and does not require a lock since - // it runs on a single thread. - Vector<Response> mResponses; - size_t mResponseIndex; - nsecs_t mNextMessageUptime; // set to LLONG_MAX when none - - int pollInner(int timeoutMillis); - void awoken(); - void pushResponse(int events, const Request& request); - - static void initTLSKey(); - static void threadDestructor(void *st); -}; - -} // namespace android - -#endif // UTILS_LOOPER_H diff --git a/include/utils/LruCache.h b/include/utils/LruCache.h deleted file mode 100644 index 053bfaf..0000000 --- a/include/utils/LruCache.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2012 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_UTILS_LRU_CACHE_H -#define ANDROID_UTILS_LRU_CACHE_H - -#include <utils/BasicHashtable.h> -#include <utils/UniquePtr.h> - -namespace android { - -/** - * GenerationCache callback used when an item is removed - */ -template<typename EntryKey, typename EntryValue> -class OnEntryRemoved { -public: - virtual ~OnEntryRemoved() { }; - virtual void operator()(EntryKey& key, EntryValue& value) = 0; -}; // class OnEntryRemoved - -template <typename TKey, typename TValue> -class LruCache { -public: - explicit LruCache(uint32_t maxCapacity); - - enum Capacity { - kUnlimitedCapacity, - }; - - void setOnEntryRemovedListener(OnEntryRemoved<TKey, TValue>* listener); - size_t size() const; - const TValue& get(const TKey& key); - bool put(const TKey& key, const TValue& value); - bool remove(const TKey& key); - bool removeOldest(); - void clear(); - - class Iterator { - public: - Iterator(const LruCache<TKey, TValue>& cache): mCache(cache), mIndex(-1) { - } - - bool next() { - mIndex = mCache.mTable->next(mIndex); - return mIndex != -1; - } - - size_t index() const { - return mIndex; - } - - const TValue& value() const { - return mCache.mTable->entryAt(mIndex).value; - } - - const TKey& key() const { - return mCache.mTable->entryAt(mIndex).key; - } - private: - const LruCache<TKey, TValue>& mCache; - size_t mIndex; - }; - -private: - LruCache(const LruCache& that); // disallow copy constructor - - struct Entry { - TKey key; - TValue value; - Entry* parent; - Entry* child; - - Entry(TKey key_, TValue value_) : key(key_), value(value_), parent(NULL), child(NULL) { - } - const TKey& getKey() const { return key; } - }; - - void attachToCache(Entry& entry); - void detachFromCache(Entry& entry); - void rehash(size_t newCapacity); - - UniquePtr<BasicHashtable<TKey, Entry> > mTable; - OnEntryRemoved<TKey, TValue>* mListener; - Entry* mOldest; - Entry* mYoungest; - uint32_t mMaxCapacity; - TValue mNullValue; -}; - -// Implementation is here, because it's fully templated -template <typename TKey, typename TValue> -LruCache<TKey, TValue>::LruCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity), - mNullValue(NULL), mTable(new BasicHashtable<TKey, Entry>), mYoungest(NULL), mOldest(NULL), - mListener(NULL) { -}; - -template<typename K, typename V> -void LruCache<K, V>::setOnEntryRemovedListener(OnEntryRemoved<K, V>* listener) { - mListener = listener; -} - -template <typename TKey, typename TValue> -size_t LruCache<TKey, TValue>::size() const { - return mTable->size(); -} - -template <typename TKey, typename TValue> -const TValue& LruCache<TKey, TValue>::get(const TKey& key) { - hash_t hash = hash_type(key); - ssize_t index = mTable->find(-1, hash, key); - if (index == -1) { - return mNullValue; - } - Entry& entry = mTable->editEntryAt(index); - detachFromCache(entry); - attachToCache(entry); - return entry.value; -} - -template <typename TKey, typename TValue> -bool LruCache<TKey, TValue>::put(const TKey& key, const TValue& value) { - if (mMaxCapacity != kUnlimitedCapacity && size() >= mMaxCapacity) { - removeOldest(); - } - - hash_t hash = hash_type(key); - ssize_t index = mTable->find(-1, hash, key); - if (index >= 0) { - return false; - } - if (!mTable->hasMoreRoom()) { - rehash(mTable->capacity() * 2); - } - - // Would it be better to initialize a blank entry and assign key, value? - Entry initEntry(key, value); - index = mTable->add(hash, initEntry); - Entry& entry = mTable->editEntryAt(index); - attachToCache(entry); - return true; -} - -template <typename TKey, typename TValue> -bool LruCache<TKey, TValue>::remove(const TKey& key) { - hash_t hash = hash_type(key); - ssize_t index = mTable->find(-1, hash, key); - if (index < 0) { - return false; - } - Entry& entry = mTable->editEntryAt(index); - if (mListener) { - (*mListener)(entry.key, entry.value); - } - detachFromCache(entry); - mTable->removeAt(index); - return true; -} - -template <typename TKey, typename TValue> -bool LruCache<TKey, TValue>::removeOldest() { - if (mOldest != NULL) { - return remove(mOldest->key); - // TODO: should probably abort if false - } - return false; -} - -template <typename TKey, typename TValue> -void LruCache<TKey, TValue>::clear() { - if (mListener) { - for (Entry* p = mOldest; p != NULL; p = p->child) { - (*mListener)(p->key, p->value); - } - } - mYoungest = NULL; - mOldest = NULL; - mTable->clear(); -} - -template <typename TKey, typename TValue> -void LruCache<TKey, TValue>::attachToCache(Entry& entry) { - if (mYoungest == NULL) { - mYoungest = mOldest = &entry; - } else { - entry.parent = mYoungest; - mYoungest->child = &entry; - mYoungest = &entry; - } -} - -template <typename TKey, typename TValue> -void LruCache<TKey, TValue>::detachFromCache(Entry& entry) { - if (entry.parent != NULL) { - entry.parent->child = entry.child; - } else { - mOldest = entry.child; - } - if (entry.child != NULL) { - entry.child->parent = entry.parent; - } else { - mYoungest = entry.parent; - } - - entry.parent = NULL; - entry.child = NULL; -} - -template <typename TKey, typename TValue> -void LruCache<TKey, TValue>::rehash(size_t newCapacity) { - UniquePtr<BasicHashtable<TKey, Entry> > oldTable(mTable.release()); - Entry* oldest = mOldest; - - mOldest = NULL; - mYoungest = NULL; - mTable.reset(new BasicHashtable<TKey, Entry>(newCapacity)); - for (Entry* p = oldest; p != NULL; p = p->child) { - put(p->key, p->value); - } -} - -} - -#endif // ANDROID_UTILS_LRU_CACHE_H diff --git a/include/utils/Mutex.h b/include/utils/Mutex.h deleted file mode 100644 index dd201c8..0000000 --- a/include/utils/Mutex.h +++ /dev/null @@ -1,137 +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 _LIBS_UTILS_MUTEX_H -#define _LIBS_UTILS_MUTEX_H - -#include <stdint.h> -#include <sys/types.h> -#include <time.h> - -#if defined(HAVE_PTHREADS) -# include <pthread.h> -#endif - -#include <utils/Errors.h> - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -class Condition; - -/* - * Simple mutex class. The implementation is system-dependent. - * - * The mutex must be unlocked by the thread that locked it. They are not - * recursive, i.e. the same thread can't lock it multiple times. - */ -class Mutex { -public: - enum { - PRIVATE = 0, - SHARED = 1 - }; - - Mutex(); - Mutex(const char* name); - Mutex(int type, const char* name = NULL); - ~Mutex(); - - // lock or unlock the mutex - status_t lock(); - void unlock(); - - // lock if possible; returns 0 on success, error otherwise - status_t tryLock(); - - // Manages the mutex automatically. It'll be locked when Autolock is - // constructed and released when Autolock goes out of scope. - class Autolock { - public: - inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } - inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } - inline ~Autolock() { mLock.unlock(); } - private: - Mutex& mLock; - }; - -private: - friend class Condition; - - // A mutex cannot be copied - Mutex(const Mutex&); - Mutex& operator = (const Mutex&); - -#if defined(HAVE_PTHREADS) - pthread_mutex_t mMutex; -#else - void _init(); - void* mState; -#endif -}; - -// --------------------------------------------------------------------------- - -#if defined(HAVE_PTHREADS) - -inline Mutex::Mutex() { - pthread_mutex_init(&mMutex, NULL); -} -inline Mutex::Mutex(__attribute__((unused)) const char* name) { - pthread_mutex_init(&mMutex, NULL); -} -inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) { - if (type == SHARED) { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - pthread_mutex_init(&mMutex, &attr); - pthread_mutexattr_destroy(&attr); - } else { - pthread_mutex_init(&mMutex, NULL); - } -} -inline Mutex::~Mutex() { - pthread_mutex_destroy(&mMutex); -} -inline status_t Mutex::lock() { - return -pthread_mutex_lock(&mMutex); -} -inline void Mutex::unlock() { - pthread_mutex_unlock(&mMutex); -} -inline status_t Mutex::tryLock() { - return -pthread_mutex_trylock(&mMutex); -} - -#endif // HAVE_PTHREADS - -// --------------------------------------------------------------------------- - -/* - * Automatic mutex. Declare one of these at the top of a function. - * When the function returns, it will go out of scope, and release the - * mutex. - */ - -typedef Mutex::Autolock AutoMutex; - -// --------------------------------------------------------------------------- -}; // namespace android -// --------------------------------------------------------------------------- - -#endif // _LIBS_UTILS_MUTEX_H diff --git a/include/utils/PropertyMap.h b/include/utils/PropertyMap.h deleted file mode 100644 index a9e674f..0000000 --- a/include/utils/PropertyMap.h +++ /dev/null @@ -1,106 +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 _UTILS_PROPERTY_MAP_H -#define _UTILS_PROPERTY_MAP_H - -#include <utils/KeyedVector.h> -#include <utils/String8.h> -#include <utils/Errors.h> -#include <utils/Tokenizer.h> - -namespace android { - -/* - * Provides a mechanism for passing around string-based property key / value pairs - * and loading them from property files. - * - * The property files have the following simple structure: - * - * # Comment - * key = value - * - * Keys and values are any sequence of printable ASCII characters. - * The '=' separates the key from the value. - * The key and value may not contain whitespace. - * - * The '\' character is reserved for escape sequences and is not currently supported. - * The '"" character is reserved for quoting and is not currently supported. - * Files that contain the '\' or '"' character will fail to parse. - * - * The file must not contain duplicate keys. - * - * TODO Support escape sequences and quoted values when needed. - */ -class PropertyMap { -public: - /* Creates an empty property map. */ - PropertyMap(); - ~PropertyMap(); - - /* Clears the property map. */ - void clear(); - - /* Adds a property. - * Replaces the property with the same key if it is already present. - */ - void addProperty(const String8& key, const String8& value); - - /* Returns true if the property map contains the specified key. */ - bool hasProperty(const String8& key) const; - - /* Gets the value of a property and parses it. - * Returns true and sets outValue if the key was found and its value was parsed successfully. - * Otherwise returns false and does not modify outValue. (Also logs a warning.) - */ - bool tryGetProperty(const String8& key, String8& outValue) const; - bool tryGetProperty(const String8& key, bool& outValue) const; - bool tryGetProperty(const String8& key, int32_t& outValue) const; - bool tryGetProperty(const String8& key, float& outValue) const; - - /* Adds all values from the specified property map. */ - void addAll(const PropertyMap* map); - - /* Gets the underlying property map. */ - inline const KeyedVector<String8, String8>& getProperties() const { return mProperties; } - - /* Loads a property map from a file. */ - static status_t load(const String8& filename, PropertyMap** outMap); - -private: - class Parser { - PropertyMap* mMap; - Tokenizer* mTokenizer; - - public: - Parser(PropertyMap* map, Tokenizer* tokenizer); - ~Parser(); - status_t parse(); - - private: - status_t parseType(); - status_t parseKey(); - status_t parseKeyProperty(); - status_t parseModifier(const String8& token, int32_t* outMetaState); - status_t parseCharacterLiteral(char16_t* outCharacter); - }; - - KeyedVector<String8, String8> mProperties; -}; - -} // namespace android - -#endif // _UTILS_PROPERTY_MAP_H diff --git a/include/utils/RWLock.h b/include/utils/RWLock.h deleted file mode 100644 index 90beb5f..0000000 --- a/include/utils/RWLock.h +++ /dev/null @@ -1,126 +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 _LIBS_UTILS_RWLOCK_H -#define _LIBS_UTILS_RWLOCK_H - -#include <stdint.h> -#include <sys/types.h> - -#if defined(HAVE_PTHREADS) -# include <pthread.h> -#endif - -#include <utils/Errors.h> -#include <utils/ThreadDefs.h> - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -#if defined(HAVE_PTHREADS) - -/* - * Simple mutex class. The implementation is system-dependent. - * - * The mutex must be unlocked by the thread that locked it. They are not - * recursive, i.e. the same thread can't lock it multiple times. - */ -class RWLock { -public: - enum { - PRIVATE = 0, - SHARED = 1 - }; - - RWLock(); - RWLock(const char* name); - RWLock(int type, const char* name = NULL); - ~RWLock(); - - status_t readLock(); - status_t tryReadLock(); - status_t writeLock(); - status_t tryWriteLock(); - void unlock(); - - class AutoRLock { - public: - inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); } - inline ~AutoRLock() { mLock.unlock(); } - private: - RWLock& mLock; - }; - - class AutoWLock { - public: - inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); } - inline ~AutoWLock() { mLock.unlock(); } - private: - RWLock& mLock; - }; - -private: - // A RWLock cannot be copied - RWLock(const RWLock&); - RWLock& operator = (const RWLock&); - - pthread_rwlock_t mRWLock; -}; - -inline RWLock::RWLock() { - pthread_rwlock_init(&mRWLock, NULL); -} -inline RWLock::RWLock(__attribute__((unused)) const char* name) { - pthread_rwlock_init(&mRWLock, NULL); -} -inline RWLock::RWLock(int type, __attribute__((unused)) const char* name) { - if (type == SHARED) { - pthread_rwlockattr_t attr; - pthread_rwlockattr_init(&attr); - pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - pthread_rwlock_init(&mRWLock, &attr); - pthread_rwlockattr_destroy(&attr); - } else { - pthread_rwlock_init(&mRWLock, NULL); - } -} -inline RWLock::~RWLock() { - pthread_rwlock_destroy(&mRWLock); -} -inline status_t RWLock::readLock() { - return -pthread_rwlock_rdlock(&mRWLock); -} -inline status_t RWLock::tryReadLock() { - return -pthread_rwlock_tryrdlock(&mRWLock); -} -inline status_t RWLock::writeLock() { - return -pthread_rwlock_wrlock(&mRWLock); -} -inline status_t RWLock::tryWriteLock() { - return -pthread_rwlock_trywrlock(&mRWLock); -} -inline void RWLock::unlock() { - pthread_rwlock_unlock(&mRWLock); -} - -#endif // HAVE_PTHREADS - -// --------------------------------------------------------------------------- -}; // namespace android -// --------------------------------------------------------------------------- - -#endif // _LIBS_UTILS_RWLOCK_H diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h deleted file mode 100644 index 033fe67..0000000 --- a/include/utils/RefBase.h +++ /dev/null @@ -1,546 +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_REF_BASE_H -#define ANDROID_REF_BASE_H - -#include <cutils/atomic.h> - -#include <stdint.h> -#include <sys/types.h> -#include <stdlib.h> -#include <string.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; \ -} - -// --------------------------------------------------------------------------- - -class ReferenceRenamer { -protected: - // destructor is purposedly 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; -}; - -// --------------------------------------------------------------------------- - -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 - }; - - virtual void onFirstRef(); - virtual void onLastStrongRef(const void* id); - virtual bool onIncStrongAttempted(uint32_t flags, const void* id); - 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 <class T> -class LightRefBase -{ -public: - inline LightRefBase() : mCount(0) { } - inline void incStrong(__attribute__((unused)) const void* id) const { - android_atomic_inc(&mCount); - } - inline void decStrong(__attribute__((unused)) const void* id) const { - if (android_atomic_dec(&mCount) == 1) { - delete static_cast<const T*>(this); - } - } - //! DEBUGGING ONLY: Get current strong ref count. - inline int32_t getStrongCount() const { - return mCount; - } - - 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 volatile int32_t mCount; -}; - -// --------------------------------------------------------------------------- - -template <typename T> -class wp -{ -public: - typedef typename RefBase::weakref_type weakref_type; - - inline wp() : m_ptr(0) { } - - wp(T* other); - wp(const wp<T>& other); - wp(const sp<T>& other); - template<typename U> wp(U* other); - template<typename U> wp(const sp<U>& other); - template<typename U> wp(const wp<U>& other); - - ~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>* d, sp<TYPE> const* s, 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) : s(s), d(d) { } - }; - - memmove(d, s, n*sizeof(sp<TYPE>)); - TYPE::renameRefs(n, Renamer(d, s)); - } - - - template<typename TYPE> static inline - void move_references(wp<TYPE>* d, wp<TYPE> const* s, 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>* d, wp<TYPE> const* s) : s(s), d(d) { } - }; - - memmove(d, s, n*sizeof(wp<TYPE>)); - TYPE::renameRefs(n, Renamer(d, s)); - } -}; - -// 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/include/utils/SharedBuffer.h b/include/utils/SharedBuffer.h deleted file mode 100644 index b670953..0000000 --- a/include/utils/SharedBuffer.h +++ /dev/null @@ -1,137 +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_SHARED_BUFFER_H -#define ANDROID_SHARED_BUFFER_H - -#include <stdint.h> -#include <sys/types.h> - -// --------------------------------------------------------------------------- - -namespace android { - -class SharedBuffer -{ -public: - - /* flags to use with release() */ - enum { - eKeepStorage = 0x00000001 - }; - - /*! allocate a buffer of size 'size' and acquire() it. - * call release() to free it. - */ - static SharedBuffer* alloc(size_t size); - - /*! free the memory associated with the SharedBuffer. - * Fails if there are any users associated with this SharedBuffer. - * In other words, the buffer must have been release by all its - * users. - */ - static ssize_t dealloc(const SharedBuffer* released); - - //! access the data for read - inline const void* data() const; - - //! access the data for read/write - inline void* data(); - - //! get size of the buffer - inline size_t size() const; - - //! get back a SharedBuffer object from its data - static inline SharedBuffer* bufferFromData(void* data); - - //! get back a SharedBuffer object from its data - static inline const SharedBuffer* bufferFromData(const void* data); - - //! get the size of a SharedBuffer object from its data - static inline size_t sizeFromData(const void* data); - - //! edit the buffer (get a writtable, or non-const, version of it) - SharedBuffer* edit() const; - - //! edit the buffer, resizing if needed - SharedBuffer* editResize(size_t size) const; - - //! like edit() but fails if a copy is required - SharedBuffer* attemptEdit() const; - - //! resize and edit the buffer, loose it's content. - SharedBuffer* reset(size_t size) const; - - //! acquire/release a reference on this buffer - void acquire() const; - - /*! release a reference on this buffer, with the option of not - * freeing the memory associated with it if it was the last reference - * returns the previous reference count - */ - int32_t release(uint32_t flags = 0) const; - - //! returns wether or not we're the only owner - inline bool onlyOwner() const; - - -private: - inline SharedBuffer() { } - inline ~SharedBuffer() { } - SharedBuffer(const SharedBuffer&); - SharedBuffer& operator = (const SharedBuffer&); - - // 16 bytes. must be sized to preserve correct alignment. - mutable int32_t mRefs; - size_t mSize; - uint32_t mReserved[2]; -}; - -// --------------------------------------------------------------------------- - -const void* SharedBuffer::data() const { - return this + 1; -} - -void* SharedBuffer::data() { - return this + 1; -} - -size_t SharedBuffer::size() const { - return mSize; -} - -SharedBuffer* SharedBuffer::bufferFromData(void* data) { - return data ? static_cast<SharedBuffer *>(data)-1 : 0; -} - -const SharedBuffer* SharedBuffer::bufferFromData(const void* data) { - return data ? static_cast<const SharedBuffer *>(data)-1 : 0; -} - -size_t SharedBuffer::sizeFromData(const void* data) { - return data ? bufferFromData(data)->mSize : 0; -} - -bool SharedBuffer::onlyOwner() const { - return (mRefs == 1); -} - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_VECTOR_H diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h deleted file mode 100644 index c60680e..0000000 --- a/include/utils/Singleton.h +++ /dev/null @@ -1,77 +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_UTILS_SINGLETON_H -#define ANDROID_UTILS_SINGLETON_H - -#include <stdint.h> -#include <sys/types.h> -#include <utils/threads.h> -#include <cutils/compiler.h> - -namespace android { -// --------------------------------------------------------------------------- - -template <typename TYPE> -class ANDROID_API Singleton -{ -public: - static TYPE& getInstance() { - Mutex::Autolock _l(sLock); - TYPE* instance = sInstance; - if (instance == 0) { - instance = new TYPE(); - sInstance = instance; - } - return *instance; - } - - static bool hasInstance() { - Mutex::Autolock _l(sLock); - return sInstance != 0; - } - -protected: - ~Singleton() { }; - Singleton() { }; - -private: - Singleton(const Singleton&); - Singleton& operator = (const Singleton&); - static Mutex sLock; - static TYPE* sInstance; -}; - -/* - * use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file - * (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes, - * and avoid to have a copy of them in each compilation units Singleton<TYPE> - * is used. - * NOTE: we use a version of Mutex ctor that takes a parameter, because - * for some unknown reason using the default ctor doesn't emit the variable! - */ - -#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \ - template<> Mutex Singleton< TYPE >::sLock(Mutex::PRIVATE); \ - template<> TYPE* Singleton< TYPE >::sInstance(0); \ - template class Singleton< TYPE >; - - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_UTILS_SINGLETON_H - diff --git a/include/utils/SortedVector.h b/include/utils/SortedVector.h deleted file mode 100644 index 2d3e82a..0000000 --- a/include/utils/SortedVector.h +++ /dev/null @@ -1,282 +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_SORTED_VECTOR_H -#define ANDROID_SORTED_VECTOR_H - -#include <assert.h> -#include <stdint.h> -#include <sys/types.h> - -#include <cutils/log.h> - -#include <utils/Vector.h> -#include <utils/VectorImpl.h> -#include <utils/TypeHelpers.h> - -// --------------------------------------------------------------------------- - -namespace android { - -template <class TYPE> -class SortedVector : private SortedVectorImpl -{ - friend class Vector<TYPE>; - -public: - typedef TYPE value_type; - - /*! - * Constructors and destructors - */ - - SortedVector(); - SortedVector(const SortedVector<TYPE>& rhs); - virtual ~SortedVector(); - - /*! copy operator */ - const SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const; - SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs); - - /* - * empty the vector - */ - - inline void clear() { VectorImpl::clear(); } - - /*! - * vector stats - */ - - //! returns number of items in the vector - inline size_t size() const { return VectorImpl::size(); } - //! returns whether or not the vector is empty - inline bool isEmpty() const { return VectorImpl::isEmpty(); } - //! returns how many items can be stored without reallocating the backing store - inline size_t capacity() const { return VectorImpl::capacity(); } - //! sets the capacity. capacity can never be reduced less than size() - inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); } - - /*! - * C-style array access - */ - - //! read-only C-style access - inline const TYPE* array() const; - - //! read-write C-style access. BE VERY CAREFUL when modifying the array - //! you must keep it sorted! You usually don't use this function. - TYPE* editArray(); - - //! finds the index of an item - ssize_t indexOf(const TYPE& item) const; - - //! finds where this item should be inserted - size_t orderOf(const TYPE& item) const; - - - /*! - * accessors - */ - - //! read-only access to an item at a given index - inline const TYPE& operator [] (size_t index) const; - //! alternate name for operator [] - inline const TYPE& itemAt(size_t index) const; - //! stack-usage of the vector. returns the top of the stack (last element) - const TYPE& top() const; - - /*! - * modifying the array - */ - - //! add an item in the right place (and replace the one that is there) - ssize_t add(const TYPE& item); - - //! editItemAt() MUST NOT change the order of this item - TYPE& editItemAt(size_t index) { - return *( static_cast<TYPE *>(VectorImpl::editItemLocation(index)) ); - } - - //! merges a vector into this one - ssize_t merge(const Vector<TYPE>& vector); - ssize_t merge(const SortedVector<TYPE>& vector); - - //! removes an item - ssize_t remove(const TYPE&); - - //! remove several items - inline ssize_t removeItemsAt(size_t index, size_t count = 1); - //! remove one item - inline ssize_t removeAt(size_t index) { return removeItemsAt(index); } - -protected: - virtual void do_construct(void* storage, size_t num) const; - virtual void do_destroy(void* storage, size_t num) const; - virtual void do_copy(void* dest, const void* from, size_t num) const; - virtual void do_splat(void* dest, const void* item, size_t num) const; - virtual void do_move_forward(void* dest, const void* from, size_t num) const; - virtual void do_move_backward(void* dest, const void* from, size_t num) const; - virtual int do_compare(const void* lhs, const void* rhs) const; -}; - -// SortedVector<T> can be trivially moved using memcpy() because moving does not -// require any change to the underlying SharedBuffer contents or reference count. -template<typename T> struct trait_trivial_move<SortedVector<T> > { enum { value = true }; }; - -// --------------------------------------------------------------------------- -// No user serviceable parts from here... -// --------------------------------------------------------------------------- - -template<class TYPE> inline -SortedVector<TYPE>::SortedVector() - : SortedVectorImpl(sizeof(TYPE), - ((traits<TYPE>::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) - |(traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) - |(traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0)) - ) -{ -} - -template<class TYPE> inline -SortedVector<TYPE>::SortedVector(const SortedVector<TYPE>& rhs) - : SortedVectorImpl(rhs) { -} - -template<class TYPE> inline -SortedVector<TYPE>::~SortedVector() { - finish_vector(); -} - -template<class TYPE> inline -SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) { - SortedVectorImpl::operator = (rhs); - return *this; -} - -template<class TYPE> inline -const SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const { - SortedVectorImpl::operator = (rhs); - return *this; -} - -template<class TYPE> inline -const TYPE* SortedVector<TYPE>::array() const { - return static_cast<const TYPE *>(arrayImpl()); -} - -template<class TYPE> inline -TYPE* SortedVector<TYPE>::editArray() { - return static_cast<TYPE *>(editArrayImpl()); -} - - -template<class TYPE> inline -const TYPE& SortedVector<TYPE>::operator[](size_t index) const { - LOG_FATAL_IF(index>=size(), - "%s: index=%u out of range (%u)", __PRETTY_FUNCTION__, - int(index), int(size())); - return *(array() + index); -} - -template<class TYPE> inline -const TYPE& SortedVector<TYPE>::itemAt(size_t index) const { - return operator[](index); -} - -template<class TYPE> inline -const TYPE& SortedVector<TYPE>::top() const { - return *(array() + size() - 1); -} - -template<class TYPE> inline -ssize_t SortedVector<TYPE>::add(const TYPE& item) { - return SortedVectorImpl::add(&item); -} - -template<class TYPE> inline -ssize_t SortedVector<TYPE>::indexOf(const TYPE& item) const { - return SortedVectorImpl::indexOf(&item); -} - -template<class TYPE> inline -size_t SortedVector<TYPE>::orderOf(const TYPE& item) const { - return SortedVectorImpl::orderOf(&item); -} - -template<class TYPE> inline -ssize_t SortedVector<TYPE>::merge(const Vector<TYPE>& vector) { - return SortedVectorImpl::merge(reinterpret_cast<const VectorImpl&>(vector)); -} - -template<class TYPE> inline -ssize_t SortedVector<TYPE>::merge(const SortedVector<TYPE>& vector) { - return SortedVectorImpl::merge(reinterpret_cast<const SortedVectorImpl&>(vector)); -} - -template<class TYPE> inline -ssize_t SortedVector<TYPE>::remove(const TYPE& item) { - return SortedVectorImpl::remove(&item); -} - -template<class TYPE> inline -ssize_t SortedVector<TYPE>::removeItemsAt(size_t index, size_t count) { - return VectorImpl::removeItemsAt(index, count); -} - -// --------------------------------------------------------------------------- - -template<class TYPE> -void SortedVector<TYPE>::do_construct(void* storage, size_t num) const { - construct_type( reinterpret_cast<TYPE*>(storage), num ); -} - -template<class TYPE> -void SortedVector<TYPE>::do_destroy(void* storage, size_t num) const { - destroy_type( reinterpret_cast<TYPE*>(storage), num ); -} - -template<class TYPE> -void SortedVector<TYPE>::do_copy(void* dest, const void* from, size_t num) const { - copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); -} - -template<class TYPE> -void SortedVector<TYPE>::do_splat(void* dest, const void* item, size_t num) const { - splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num ); -} - -template<class TYPE> -void SortedVector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const { - move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); -} - -template<class TYPE> -void SortedVector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const { - move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); -} - -template<class TYPE> -int SortedVector<TYPE>::do_compare(const void* lhs, const void* rhs) const { - return compare_type( *reinterpret_cast<const TYPE*>(lhs), *reinterpret_cast<const TYPE*>(rhs) ); -} - -}; // namespace android - - -// --------------------------------------------------------------------------- - -#endif // ANDROID_SORTED_VECTOR_H diff --git a/include/utils/StopWatch.h b/include/utils/StopWatch.h deleted file mode 100644 index 693dd3c..0000000 --- a/include/utils/StopWatch.h +++ /dev/null @@ -1,64 +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_STOPWATCH_H -#define ANDROID_STOPWATCH_H - -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Timers.h> - -// --------------------------------------------------------------------------- - -namespace android { - -class StopWatch -{ -public: - StopWatch( const char *name, - int clock = SYSTEM_TIME_MONOTONIC, - uint32_t flags = 0); - ~StopWatch(); - - const char* name() const; - nsecs_t lap(); - nsecs_t elapsedTime() const; - - void reset(); - -private: - const char* mName; - int mClock; - uint32_t mFlags; - - struct lap_t { - nsecs_t soFar; - nsecs_t thisLap; - }; - - nsecs_t mStartTime; - lap_t mLaps[8]; - int mNumLaps; -}; - - -}; // namespace android - - -// --------------------------------------------------------------------------- - -#endif // ANDROID_STOPWATCH_H diff --git a/include/utils/String16.h b/include/utils/String16.h deleted file mode 100644 index d131bfc..0000000 --- a/include/utils/String16.h +++ /dev/null @@ -1,250 +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_STRING16_H -#define ANDROID_STRING16_H - -#include <utils/Errors.h> -#include <utils/SharedBuffer.h> -#include <utils/Unicode.h> -#include <utils/TypeHelpers.h> - -// --------------------------------------------------------------------------- - -extern "C" { - -} - -// --------------------------------------------------------------------------- - -namespace android { - -// --------------------------------------------------------------------------- - -class String8; -class TextOutput; - -//! This is a string holding UTF-16 characters. -class String16 -{ -public: - /* use String16(StaticLinkage) if you're statically linking against - * libutils and declaring an empty static String16, e.g.: - * - * static String16 sAStaticEmptyString(String16::kEmptyString); - * static String16 sAnotherStaticEmptyString(sAStaticEmptyString); - */ - enum StaticLinkage { kEmptyString }; - - String16(); - explicit String16(StaticLinkage); - String16(const String16& o); - String16(const String16& o, - size_t len, - size_t begin=0); - explicit String16(const char16_t* o); - explicit String16(const char16_t* o, size_t len); - explicit String16(const String8& o); - explicit String16(const char* o); - explicit String16(const char* o, size_t len); - - ~String16(); - - inline const char16_t* string() const; - inline size_t size() const; - - inline const SharedBuffer* sharedBuffer() const; - - void setTo(const String16& other); - status_t setTo(const char16_t* other); - status_t setTo(const char16_t* other, size_t len); - status_t setTo(const String16& other, - size_t len, - size_t begin=0); - - status_t append(const String16& other); - status_t append(const char16_t* other, size_t len); - - inline String16& operator=(const String16& other); - - inline String16& operator+=(const String16& other); - inline String16 operator+(const String16& other) const; - - status_t insert(size_t pos, const char16_t* chrs); - status_t insert(size_t pos, - const char16_t* chrs, size_t len); - - ssize_t findFirst(char16_t c) const; - ssize_t findLast(char16_t c) const; - - bool startsWith(const String16& prefix) const; - bool startsWith(const char16_t* prefix) const; - - status_t makeLower(); - - status_t replaceAll(char16_t replaceThis, - char16_t withThis); - - status_t remove(size_t len, size_t begin=0); - - inline int compare(const String16& other) const; - - inline bool operator<(const String16& other) const; - inline bool operator<=(const String16& other) const; - inline bool operator==(const String16& other) const; - inline bool operator!=(const String16& other) const; - inline bool operator>=(const String16& other) const; - inline bool operator>(const String16& other) const; - - inline bool operator<(const char16_t* other) const; - inline bool operator<=(const char16_t* other) const; - inline bool operator==(const char16_t* other) const; - inline bool operator!=(const char16_t* other) const; - inline bool operator>=(const char16_t* other) const; - inline bool operator>(const char16_t* other) const; - - inline operator const char16_t*() const; - -private: - const char16_t* mString; -}; - -// String16 can be trivially moved using memcpy() because moving does not -// require any change to the underlying SharedBuffer contents or reference count. -ANDROID_TRIVIAL_MOVE_TRAIT(String16) - -// --------------------------------------------------------------------------- -// No user servicable parts below. - -inline int compare_type(const String16& lhs, const String16& rhs) -{ - return lhs.compare(rhs); -} - -inline int strictly_order_type(const String16& lhs, const String16& rhs) -{ - return compare_type(lhs, rhs) < 0; -} - -inline const char16_t* String16::string() const -{ - return mString; -} - -inline size_t String16::size() const -{ - return SharedBuffer::sizeFromData(mString)/sizeof(char16_t)-1; -} - -inline const SharedBuffer* String16::sharedBuffer() const -{ - return SharedBuffer::bufferFromData(mString); -} - -inline String16& String16::operator=(const String16& other) -{ - setTo(other); - return *this; -} - -inline String16& String16::operator+=(const String16& other) -{ - append(other); - return *this; -} - -inline String16 String16::operator+(const String16& other) const -{ - String16 tmp(*this); - tmp += other; - return tmp; -} - -inline int String16::compare(const String16& other) const -{ - return strzcmp16(mString, size(), other.mString, other.size()); -} - -inline bool String16::operator<(const String16& other) const -{ - return strzcmp16(mString, size(), other.mString, other.size()) < 0; -} - -inline bool String16::operator<=(const String16& other) const -{ - return strzcmp16(mString, size(), other.mString, other.size()) <= 0; -} - -inline bool String16::operator==(const String16& other) const -{ - return strzcmp16(mString, size(), other.mString, other.size()) == 0; -} - -inline bool String16::operator!=(const String16& other) const -{ - return strzcmp16(mString, size(), other.mString, other.size()) != 0; -} - -inline bool String16::operator>=(const String16& other) const -{ - return strzcmp16(mString, size(), other.mString, other.size()) >= 0; -} - -inline bool String16::operator>(const String16& other) const -{ - return strzcmp16(mString, size(), other.mString, other.size()) > 0; -} - -inline bool String16::operator<(const char16_t* other) const -{ - return strcmp16(mString, other) < 0; -} - -inline bool String16::operator<=(const char16_t* other) const -{ - return strcmp16(mString, other) <= 0; -} - -inline bool String16::operator==(const char16_t* other) const -{ - return strcmp16(mString, other) == 0; -} - -inline bool String16::operator!=(const char16_t* other) const -{ - return strcmp16(mString, other) != 0; -} - -inline bool String16::operator>=(const char16_t* other) const -{ - return strcmp16(mString, other) >= 0; -} - -inline bool String16::operator>(const char16_t* other) const -{ - return strcmp16(mString, other) > 0; -} - -inline String16::operator const char16_t*() const -{ - return mString; -} - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_STRING16_H diff --git a/include/utils/String8.h b/include/utils/String8.h deleted file mode 100644 index ef59470..0000000 --- a/include/utils/String8.h +++ /dev/null @@ -1,395 +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_STRING8_H -#define ANDROID_STRING8_H - -#include <utils/Errors.h> -#include <utils/SharedBuffer.h> -#include <utils/Unicode.h> -#include <utils/TypeHelpers.h> - -#include <string.h> // for strcmp -#include <stdarg.h> - -// --------------------------------------------------------------------------- - -namespace android { - -class String16; -class TextOutput; - -//! This is a string holding UTF-8 characters. Does not allow the value more -// than 0x10FFFF, which is not valid unicode codepoint. -class String8 -{ -public: - /* use String8(StaticLinkage) if you're statically linking against - * libutils and declaring an empty static String8, e.g.: - * - * static String8 sAStaticEmptyString(String8::kEmptyString); - * static String8 sAnotherStaticEmptyString(sAStaticEmptyString); - */ - enum StaticLinkage { kEmptyString }; - - String8(); - explicit String8(StaticLinkage); - String8(const String8& o); - explicit String8(const char* o); - explicit String8(const char* o, size_t numChars); - - explicit String8(const String16& o); - explicit String8(const char16_t* o); - explicit String8(const char16_t* o, size_t numChars); - explicit String8(const char32_t* o); - explicit String8(const char32_t* o, size_t numChars); - ~String8(); - - static inline const String8 empty(); - - static String8 format(const char* fmt, ...) __attribute__((format (printf, 1, 2))); - static String8 formatV(const char* fmt, va_list args); - - inline const char* string() const; - inline size_t size() const; - inline size_t length() const; - inline size_t bytes() const; - inline bool isEmpty() const; - - inline const SharedBuffer* sharedBuffer() const; - - void clear(); - - void setTo(const String8& other); - status_t setTo(const char* other); - status_t setTo(const char* other, size_t numChars); - status_t setTo(const char16_t* other, size_t numChars); - status_t setTo(const char32_t* other, - size_t length); - - status_t append(const String8& other); - status_t append(const char* other); - status_t append(const char* other, size_t numChars); - - status_t appendFormat(const char* fmt, ...) - __attribute__((format (printf, 2, 3))); - status_t appendFormatV(const char* fmt, va_list args); - - // Note that this function takes O(N) time to calculate the value. - // No cache value is stored. - size_t getUtf32Length() const; - int32_t getUtf32At(size_t index, - size_t *next_index) const; - void getUtf32(char32_t* dst) const; - - inline String8& operator=(const String8& other); - inline String8& operator=(const char* other); - - inline String8& operator+=(const String8& other); - inline String8 operator+(const String8& other) const; - - inline String8& operator+=(const char* other); - inline String8 operator+(const char* other) const; - - inline int compare(const String8& other) const; - - inline bool operator<(const String8& other) const; - inline bool operator<=(const String8& other) const; - inline bool operator==(const String8& other) const; - inline bool operator!=(const String8& other) const; - inline bool operator>=(const String8& other) const; - inline bool operator>(const String8& other) const; - - inline bool operator<(const char* other) const; - inline bool operator<=(const char* other) const; - inline bool operator==(const char* other) const; - inline bool operator!=(const char* other) const; - inline bool operator>=(const char* other) const; - inline bool operator>(const char* other) const; - - inline operator const char*() const; - - char* lockBuffer(size_t size); - void unlockBuffer(); - status_t unlockBuffer(size_t size); - - // return the index of the first byte of other in this at or after - // start, or -1 if not found - ssize_t find(const char* other, size_t start = 0) const; - - void toLower(); - void toLower(size_t start, size_t numChars); - void toUpper(); - void toUpper(size_t start, size_t numChars); - - /* - * These methods operate on the string as if it were a path name. - */ - - /* - * Set the filename field to a specific value. - * - * Normalizes the filename, removing a trailing '/' if present. - */ - void setPathName(const char* name); - void setPathName(const char* name, size_t numChars); - - /* - * Get just the filename component. - * - * "/tmp/foo/bar.c" --> "bar.c" - */ - String8 getPathLeaf(void) const; - - /* - * Remove the last (file name) component, leaving just the directory - * name. - * - * "/tmp/foo/bar.c" --> "/tmp/foo" - * "/tmp" --> "" // ????? shouldn't this be "/" ???? XXX - * "bar.c" --> "" - */ - String8 getPathDir(void) const; - - /* - * Retrieve the front (root dir) component. Optionally also return the - * remaining components. - * - * "/tmp/foo/bar.c" --> "tmp" (remain = "foo/bar.c") - * "/tmp" --> "tmp" (remain = "") - * "bar.c" --> "bar.c" (remain = "") - */ - String8 walkPath(String8* outRemains = NULL) const; - - /* - * Return the filename extension. This is the last '.' and any number - * of characters that follow it. The '.' is included in case we - * decide to expand our definition of what constitutes an extension. - * - * "/tmp/foo/bar.c" --> ".c" - * "/tmp" --> "" - * "/tmp/foo.bar/baz" --> "" - * "foo.jpeg" --> ".jpeg" - * "foo." --> "" - */ - String8 getPathExtension(void) const; - - /* - * Return the path without the extension. Rules for what constitutes - * an extension are described in the comment for getPathExtension(). - * - * "/tmp/foo/bar.c" --> "/tmp/foo/bar" - */ - String8 getBasePath(void) const; - - /* - * Add a component to the pathname. We guarantee that there is - * exactly one path separator between the old path and the new. - * If there is no existing name, we just copy the new name in. - * - * If leaf is a fully qualified path (i.e. starts with '/', it - * replaces whatever was there before. - */ - String8& appendPath(const char* leaf); - String8& appendPath(const String8& leaf) { return appendPath(leaf.string()); } - - /* - * Like appendPath(), but does not affect this string. Returns a new one instead. - */ - String8 appendPathCopy(const char* leaf) const - { String8 p(*this); p.appendPath(leaf); return p; } - String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.string()); } - - /* - * Converts all separators in this string to /, the default path separator. - * - * If the default OS separator is backslash, this converts all - * backslashes to slashes, in-place. Otherwise it does nothing. - * Returns self. - */ - String8& convertToResPath(); - -private: - status_t real_append(const char* other, size_t numChars); - char* find_extension(void) const; - - const char* mString; -}; - -// String8 can be trivially moved using memcpy() because moving does not -// require any change to the underlying SharedBuffer contents or reference count. -ANDROID_TRIVIAL_MOVE_TRAIT(String8) - -// --------------------------------------------------------------------------- -// No user servicable parts below. - -inline int compare_type(const String8& lhs, const String8& rhs) -{ - return lhs.compare(rhs); -} - -inline int strictly_order_type(const String8& lhs, const String8& rhs) -{ - return compare_type(lhs, rhs) < 0; -} - -inline const String8 String8::empty() { - return String8(); -} - -inline const char* String8::string() const -{ - return mString; -} - -inline size_t String8::length() const -{ - return SharedBuffer::sizeFromData(mString)-1; -} - -inline size_t String8::size() const -{ - return length(); -} - -inline bool String8::isEmpty() const -{ - return length() == 0; -} - -inline size_t String8::bytes() const -{ - return SharedBuffer::sizeFromData(mString)-1; -} - -inline const SharedBuffer* String8::sharedBuffer() const -{ - return SharedBuffer::bufferFromData(mString); -} - -inline String8& String8::operator=(const String8& other) -{ - setTo(other); - return *this; -} - -inline String8& String8::operator=(const char* other) -{ - setTo(other); - return *this; -} - -inline String8& String8::operator+=(const String8& other) -{ - append(other); - return *this; -} - -inline String8 String8::operator+(const String8& other) const -{ - String8 tmp(*this); - tmp += other; - return tmp; -} - -inline String8& String8::operator+=(const char* other) -{ - append(other); - return *this; -} - -inline String8 String8::operator+(const char* other) const -{ - String8 tmp(*this); - tmp += other; - return tmp; -} - -inline int String8::compare(const String8& other) const -{ - return strcmp(mString, other.mString); -} - -inline bool String8::operator<(const String8& other) const -{ - return strcmp(mString, other.mString) < 0; -} - -inline bool String8::operator<=(const String8& other) const -{ - return strcmp(mString, other.mString) <= 0; -} - -inline bool String8::operator==(const String8& other) const -{ - return strcmp(mString, other.mString) == 0; -} - -inline bool String8::operator!=(const String8& other) const -{ - return strcmp(mString, other.mString) != 0; -} - -inline bool String8::operator>=(const String8& other) const -{ - return strcmp(mString, other.mString) >= 0; -} - -inline bool String8::operator>(const String8& other) const -{ - return strcmp(mString, other.mString) > 0; -} - -inline bool String8::operator<(const char* other) const -{ - return strcmp(mString, other) < 0; -} - -inline bool String8::operator<=(const char* other) const -{ - return strcmp(mString, other) <= 0; -} - -inline bool String8::operator==(const char* other) const -{ - return strcmp(mString, other) == 0; -} - -inline bool String8::operator!=(const char* other) const -{ - return strcmp(mString, other) != 0; -} - -inline bool String8::operator>=(const char* other) const -{ - return strcmp(mString, other) >= 0; -} - -inline bool String8::operator>(const char* other) const -{ - return strcmp(mString, other) > 0; -} - -inline String8::operator const char*() const -{ - return mString; -} - -} // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_STRING8_H diff --git a/include/utils/StrongPointer.h b/include/utils/StrongPointer.h deleted file mode 100644 index aba9577..0000000 --- a/include/utils/StrongPointer.h +++ /dev/null @@ -1,211 +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 - -#include <cutils/atomic.h> - -#include <stdint.h> -#include <sys/types.h> -#include <stdlib.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); - sp(const sp<T>& other); - template<typename U> sp(U* other); - template<typename U> sp(const sp<U>& other); - - ~sp(); - - // Assignment - - sp& operator = (T* other); - sp& operator = (const sp<T>& other); - - template<typename U> sp& operator = (const 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; -}; - -#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> template<typename U> -sp<T>::sp(U* other) - : m_ptr(other) { - if (other) - ((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> -sp<T>::~sp() { - if (m_ptr) - m_ptr->decStrong(this); -} - -template<typename T> -sp<T>& sp<T>::operator =(const sp<T>& other) { - T* otherPtr(other.m_ptr); - if (otherPtr) - otherPtr->incStrong(this); - if (m_ptr) - m_ptr->decStrong(this); - m_ptr = otherPtr; - return *this; -} - -template<typename T> -sp<T>& sp<T>::operator =(T* other) { - if (other) - other->incStrong(this); - if (m_ptr) - m_ptr->decStrong(this); - m_ptr = other; - return *this; -} - -template<typename T> template<typename U> -sp<T>& sp<T>::operator =(const sp<U>& other) { - T* otherPtr(other.m_ptr); - if (otherPtr) - otherPtr->incStrong(this); - if (m_ptr) - m_ptr->decStrong(this); - m_ptr = otherPtr; - return *this; -} - -template<typename T> template<typename U> -sp<T>& sp<T>::operator =(U* other) { - if (other) - ((T*) other)->incStrong(this); - if (m_ptr) - m_ptr->decStrong(this); - 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/include/utils/SystemClock.h b/include/utils/SystemClock.h deleted file mode 100644 index 01db340..0000000 --- a/include/utils/SystemClock.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2008 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_UTILS_SYSTEMCLOCK_H -#define ANDROID_UTILS_SYSTEMCLOCK_H - -#include <stdint.h> -#include <sys/types.h> - -namespace android { - -int64_t uptimeMillis(); -int64_t elapsedRealtime(); -int64_t elapsedRealtimeNano(); - -}; // namespace android - -#endif // ANDROID_UTILS_SYSTEMCLOCK_H - diff --git a/include/utils/Thread.h b/include/utils/Thread.h deleted file mode 100644 index df30611..0000000 --- a/include/utils/Thread.h +++ /dev/null @@ -1,116 +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 _LIBS_UTILS_THREAD_H -#define _LIBS_UTILS_THREAD_H - -#include <stdint.h> -#include <sys/types.h> -#include <time.h> - -#if defined(HAVE_PTHREADS) -# include <pthread.h> -#endif - -#include <utils/Condition.h> -#include <utils/Errors.h> -#include <utils/Mutex.h> -#include <utils/RefBase.h> -#include <utils/Timers.h> -#include <utils/ThreadDefs.h> - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -class Thread : virtual public RefBase -{ -public: - // Create a Thread object, but doesn't create or start the associated - // thread. See the run() method. - Thread(bool canCallJava = true); - virtual ~Thread(); - - // Start the thread in threadLoop() which needs to be implemented. - virtual status_t run( const char* name = 0, - int32_t priority = PRIORITY_DEFAULT, - size_t stack = 0); - - // Ask this object's thread to exit. This function is asynchronous, when the - // function returns the thread might still be running. Of course, this - // function can be called from a different thread. - virtual void requestExit(); - - // Good place to do one-time initializations - virtual status_t readyToRun(); - - // Call requestExit() and wait until this object's thread exits. - // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call - // this function from this object's thread. Will return WOULD_BLOCK in - // that case. - status_t requestExitAndWait(); - - // Wait until this object's thread exits. Returns immediately if not yet running. - // Do not call from this object's thread; will return WOULD_BLOCK in that case. - status_t join(); - - // Indicates whether this thread is running or not. - bool isRunning() const; - -#ifdef HAVE_ANDROID_OS - // Return the thread's kernel ID, same as the thread itself calling gettid() or - // androidGetTid(), or -1 if the thread is not running. - pid_t getTid() const; -#endif - -protected: - // exitPending() returns true if requestExit() has been called. - bool exitPending() const; - -private: - // Derived class must implement threadLoop(). The thread starts its life - // here. There are two ways of using the Thread object: - // 1) loop: if threadLoop() returns true, it will be called again if - // requestExit() wasn't called. - // 2) once: if threadLoop() returns false, the thread will exit upon return. - virtual bool threadLoop() = 0; - -private: - Thread& operator=(const Thread&); - static int _threadLoop(void* user); - const bool mCanCallJava; - // always hold mLock when reading or writing - thread_id_t mThread; - mutable Mutex mLock; - Condition mThreadExitedCondition; - status_t mStatus; - // note that all accesses of mExitPending and mRunning need to hold mLock - volatile bool mExitPending; - volatile bool mRunning; - sp<Thread> mHoldSelf; -#ifdef HAVE_ANDROID_OS - // legacy for debugging, not used by getTid() as it is set by the child thread - // and so is not initialized until the child reaches that point - pid_t mTid; -#endif -}; - - -}; // namespace android - -// --------------------------------------------------------------------------- -#endif // _LIBS_UTILS_THREAD_H -// --------------------------------------------------------------------------- diff --git a/include/utils/ThreadDefs.h b/include/utils/ThreadDefs.h deleted file mode 100644 index 9711c13..0000000 --- a/include/utils/ThreadDefs.h +++ /dev/null @@ -1,70 +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 _LIBS_UTILS_THREAD_DEFS_H -#define _LIBS_UTILS_THREAD_DEFS_H - -#include <stdint.h> -#include <sys/types.h> -#include <system/graphics.h> -#include <system/thread_defs.h> - -// --------------------------------------------------------------------------- -// C API - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void* android_thread_id_t; - -typedef int (*android_thread_func_t)(void*); - -#ifdef __cplusplus -} // extern "C" -#endif - -// --------------------------------------------------------------------------- -// C++ API -#ifdef __cplusplus -namespace android { -// --------------------------------------------------------------------------- - -typedef android_thread_id_t thread_id_t; -typedef android_thread_func_t thread_func_t; - -enum { - PRIORITY_LOWEST = ANDROID_PRIORITY_LOWEST, - PRIORITY_BACKGROUND = ANDROID_PRIORITY_BACKGROUND, - PRIORITY_NORMAL = ANDROID_PRIORITY_NORMAL, - PRIORITY_FOREGROUND = ANDROID_PRIORITY_FOREGROUND, - PRIORITY_DISPLAY = ANDROID_PRIORITY_DISPLAY, - PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY, - PRIORITY_AUDIO = ANDROID_PRIORITY_AUDIO, - PRIORITY_URGENT_AUDIO = ANDROID_PRIORITY_URGENT_AUDIO, - PRIORITY_HIGHEST = ANDROID_PRIORITY_HIGHEST, - PRIORITY_DEFAULT = ANDROID_PRIORITY_DEFAULT, - PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE, - PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE, -}; - -// --------------------------------------------------------------------------- -}; // namespace android -#endif // __cplusplus -// --------------------------------------------------------------------------- - - -#endif // _LIBS_UTILS_THREAD_DEFS_H diff --git a/include/utils/Timers.h b/include/utils/Timers.h deleted file mode 100644 index d015421..0000000 --- a/include/utils/Timers.h +++ /dev/null @@ -1,106 +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. - */ - -// -// Timer functions. -// -#ifndef _LIBS_UTILS_TIMERS_H -#define _LIBS_UTILS_TIMERS_H - -#include <stdint.h> -#include <sys/types.h> -#include <sys/time.h> - -// ------------------------------------------------------------------ -// C API - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int64_t nsecs_t; // nano-seconds - -static inline nsecs_t seconds_to_nanoseconds(nsecs_t secs) -{ - return secs*1000000000; -} - -static inline nsecs_t milliseconds_to_nanoseconds(nsecs_t secs) -{ - return secs*1000000; -} - -static inline nsecs_t microseconds_to_nanoseconds(nsecs_t secs) -{ - return secs*1000; -} - -static inline nsecs_t nanoseconds_to_seconds(nsecs_t secs) -{ - return secs/1000000000; -} - -static inline nsecs_t nanoseconds_to_milliseconds(nsecs_t secs) -{ - return secs/1000000; -} - -static inline nsecs_t nanoseconds_to_microseconds(nsecs_t secs) -{ - return secs/1000; -} - -static inline nsecs_t s2ns(nsecs_t v) {return seconds_to_nanoseconds(v);} -static inline nsecs_t ms2ns(nsecs_t v) {return milliseconds_to_nanoseconds(v);} -static inline nsecs_t us2ns(nsecs_t v) {return microseconds_to_nanoseconds(v);} -static inline nsecs_t ns2s(nsecs_t v) {return nanoseconds_to_seconds(v);} -static inline nsecs_t ns2ms(nsecs_t v) {return nanoseconds_to_milliseconds(v);} -static inline nsecs_t ns2us(nsecs_t v) {return nanoseconds_to_microseconds(v);} - -static inline nsecs_t seconds(nsecs_t v) { return s2ns(v); } -static inline nsecs_t milliseconds(nsecs_t v) { return ms2ns(v); } -static inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); } - -enum { - SYSTEM_TIME_REALTIME = 0, // system-wide realtime clock - SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point - SYSTEM_TIME_PROCESS = 2, // high-resolution per-process clock - SYSTEM_TIME_THREAD = 3, // high-resolution per-thread clock - SYSTEM_TIME_BOOTTIME = 4 // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time -}; - -// return the system-time according to the specified clock -#ifdef __cplusplus -nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC); -#else -nsecs_t systemTime(int clock); -#endif // def __cplusplus - -/** - * Returns the number of milliseconds to wait between the reference time and the timeout time. - * If the timeout is in the past relative to the reference time, returns 0. - * If the timeout is more than INT_MAX milliseconds in the future relative to the reference time, - * such as when timeoutTime == LLONG_MAX, returns -1 to indicate an infinite timeout delay. - * Otherwise, returns the difference between the reference time and timeout time - * rounded up to the next millisecond. - */ -int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _LIBS_UTILS_TIMERS_H diff --git a/include/utils/Tokenizer.h b/include/utils/Tokenizer.h deleted file mode 100644 index bb25f37..0000000 --- a/include/utils/Tokenizer.h +++ /dev/null @@ -1,136 +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 _UTILS_TOKENIZER_H -#define _UTILS_TOKENIZER_H - -#include <assert.h> -#include <utils/Errors.h> -#include <utils/FileMap.h> -#include <utils/String8.h> - -namespace android { - -/** - * A simple tokenizer for loading and parsing ASCII text files line by line. - */ -class Tokenizer { - Tokenizer(const String8& filename, FileMap* fileMap, char* buffer, - bool ownBuffer, size_t length); - -public: - ~Tokenizer(); - - /** - * Opens a file and maps it into memory. - * - * Returns NO_ERROR and a tokenizer for the file, if successful. - * Otherwise returns an error and sets outTokenizer to NULL. - */ - static status_t open(const String8& filename, Tokenizer** outTokenizer); - - /** - * Prepares to tokenize the contents of a string. - * - * Returns NO_ERROR and a tokenizer for the string, if successful. - * Otherwise returns an error and sets outTokenizer to NULL. - */ - static status_t fromContents(const String8& filename, - const char* contents, Tokenizer** outTokenizer); - - /** - * Returns true if at the end of the file. - */ - inline bool isEof() const { return mCurrent == getEnd(); } - - /** - * Returns true if at the end of the line or end of the file. - */ - inline bool isEol() const { return isEof() || *mCurrent == '\n'; } - - /** - * Gets the name of the file. - */ - inline String8 getFilename() const { return mFilename; } - - /** - * Gets a 1-based line number index for the current position. - */ - inline int32_t getLineNumber() const { return mLineNumber; } - - /** - * Formats a location string consisting of the filename and current line number. - * Returns a string like "MyFile.txt:33". - */ - String8 getLocation() const; - - /** - * Gets the character at the current position. - * Returns null at end of file. - */ - inline char peekChar() const { return isEof() ? '\0' : *mCurrent; } - - /** - * Gets the remainder of the current line as a string, excluding the newline character. - */ - String8 peekRemainderOfLine() const; - - /** - * Gets the character at the current position and advances past it. - * Returns null at end of file. - */ - inline char nextChar() { return isEof() ? '\0' : *(mCurrent++); } - - /** - * Gets the next token on this line stopping at the specified delimiters - * or the end of the line whichever comes first and advances past it. - * Also stops at embedded nulls. - * Returns the token or an empty string if the current character is a delimiter - * or is at the end of the line. - */ - String8 nextToken(const char* delimiters); - - /** - * Advances to the next line. - * Does nothing if already at the end of the file. - */ - void nextLine(); - - /** - * Skips over the specified delimiters in the line. - * Also skips embedded nulls. - */ - void skipDelimiters(const char* delimiters); - -private: - Tokenizer(const Tokenizer& other); // not copyable - - String8 mFilename; - FileMap* mFileMap; - char* mBuffer; - bool mOwnBuffer; - size_t mLength; - - const char* mCurrent; - int32_t mLineNumber; - - inline const char* getEnd() const { return mBuffer + mLength; } - -}; - -} // namespace android - -#endif // _UTILS_TOKENIZER_H diff --git a/include/utils/Trace.h b/include/utils/Trace.h deleted file mode 100644 index 6ee343d..0000000 --- a/include/utils/Trace.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2012 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_TRACE_H -#define ANDROID_TRACE_H - -#ifdef HAVE_ANDROID_OS - -#include <fcntl.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include <cutils/compiler.h> -#include <utils/threads.h> -#include <cutils/trace.h> - -// See <cutils/trace.h> for more ATRACE_* macros. - -// ATRACE_NAME traces the beginning and end of the current scope. To trace -// the correct start and end times this macro should be declared first in the -// scope body. -#define ATRACE_NAME(name) android::ScopedTrace ___tracer(ATRACE_TAG, name) -// ATRACE_CALL is an ATRACE_NAME that uses the current function name. -#define ATRACE_CALL() ATRACE_NAME(__FUNCTION__) - -namespace android { - -class ScopedTrace { -public: -inline ScopedTrace(uint64_t tag, const char* name) - : mTag(tag) { - atrace_begin(mTag,name); -} - -inline ~ScopedTrace() { - atrace_end(mTag); -} - -private: - uint64_t mTag; -}; - -}; // namespace android - -#else // HAVE_ANDROID_OS - -#define ATRACE_NAME(...) -#define ATRACE_CALL() - -#endif // HAVE_ANDROID_OS - -#endif // ANDROID_TRACE_H diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h deleted file mode 100644 index 13c9081..0000000 --- a/include/utils/TypeHelpers.h +++ /dev/null @@ -1,302 +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 <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--) { - new(p++) TYPE; - } - } -} - -template<typename TYPE> inline -void destroy_type(TYPE* p, size_t n) { - if (!traits<TYPE>::has_trivial_dtor) { - while (n--) { - p->~TYPE(); - p++; - } - } -} - -template<typename TYPE> inline -void copy_type(TYPE* d, const TYPE* s, size_t n) { - if (!traits<TYPE>::has_trivial_copy) { - while (n--) { - new(d) TYPE(*s); - d++, s++; - } - } else { - memcpy(d,s,n*sizeof(TYPE)); - } -} - -template<typename TYPE> inline -void splat_type(TYPE* where, const TYPE* what, size_t n) { - if (!traits<TYPE>::has_trivial_copy) { - while (n--) { - new(where) TYPE(*what); - where++; - } - } else { - while (n--) { - *where++ = *what; - } - } -} - -template<typename TYPE> inline -void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { - if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) - || traits<TYPE>::has_trivial_move) - { - memmove(d,s,n*sizeof(TYPE)); - } else { - d += n; - s += n; - while (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> inline -void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { - if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) - || traits<TYPE>::has_trivial_move) - { - memmove(d,s,n*sizeof(TYPE)); - } else { - while (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(const KEY& k, const VALUE& v) : key(k), value(v) { } - 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. - * Assumes pointers are 32bit. */ -#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) { \ - return hash_type(*reinterpret_cast<const R*>(&value)); } - -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 diff --git a/include/utils/Unicode.h b/include/utils/Unicode.h deleted file mode 100644 index 9273533..0000000 --- a/include/utils/Unicode.h +++ /dev/null @@ -1,168 +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_UNICODE_H -#define ANDROID_UNICODE_H - -#include <sys/types.h> -#include <stdint.h> - -extern "C" { - -typedef uint32_t char32_t; -typedef uint16_t char16_t; - -// Standard string functions on char16_t strings. -int strcmp16(const char16_t *, const char16_t *); -int strncmp16(const char16_t *s1, const char16_t *s2, size_t n); -size_t strlen16(const char16_t *); -size_t strnlen16(const char16_t *, size_t); -char16_t *strcpy16(char16_t *, const char16_t *); -char16_t *strncpy16(char16_t *, const char16_t *, size_t); - -// Version of comparison that supports embedded nulls. -// This is different than strncmp() because we don't stop -// at a nul character and consider the strings to be different -// if the lengths are different (thus we need to supply the -// lengths of both strings). This can also be used when -// your string is not nul-terminated as it will have the -// equivalent result as strcmp16 (unlike strncmp16). -int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2); - -// Version of strzcmp16 for comparing strings in different endianness. -int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2); - -// Standard string functions on char32_t strings. -size_t strlen32(const char32_t *); -size_t strnlen32(const char32_t *, size_t); - -/** - * Measure the length of a UTF-32 string in UTF-8. If the string is invalid - * such as containing a surrogate character, -1 will be returned. - */ -ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len); - -/** - * Stores a UTF-8 string converted from "src" in "dst", if "dst_length" is not - * large enough to store the string, the part of the "src" string is stored - * into "dst" as much as possible. See the examples for more detail. - * Returns the size actually used for storing the string. - * dst" is not null-terminated when dst_len is fully used (like strncpy). - * - * Example 1 - * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) - * "src_len" == 2 - * "dst_len" >= 7 - * -> - * Returned value == 6 - * "dst" becomes \xE3\x81\x82\xE3\x81\x84\0 - * (note that "dst" is null-terminated) - * - * Example 2 - * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) - * "src_len" == 2 - * "dst_len" == 5 - * -> - * Returned value == 3 - * "dst" becomes \xE3\x81\x82\0 - * (note that "dst" is null-terminated, but \u3044 is not stored in "dst" - * since "dst" does not have enough size to store the character) - * - * Example 3 - * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) - * "src_len" == 2 - * "dst_len" == 6 - * -> - * Returned value == 6 - * "dst" becomes \xE3\x81\x82\xE3\x81\x84 - * (note that "dst" is NOT null-terminated, like strncpy) - */ -void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst); - -/** - * Returns the unicode value at "index". - * Returns -1 when the index is invalid (equals to or more than "src_len"). - * If returned value is positive, it is able to be converted to char32_t, which - * is unsigned. Then, if "next_index" is not NULL, the next index to be used is - * stored in "next_index". "next_index" can be NULL. - */ -int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index); - - -/** - * Returns the UTF-8 length of UTF-16 string "src". - */ -ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len); - -/** - * Converts a UTF-16 string to UTF-8. The destination buffer must be large - * enough to fit the UTF-16 as measured by utf16_to_utf8_length with an added - * NULL terminator. - */ -void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst); - -/** - * Returns the length of "src" when "src" is valid UTF-8 string. - * Returns 0 if src is NULL or 0-length string. Returns -1 when the source - * is an invalid string. - * - * This function should be used to determine whether "src" is valid UTF-8 - * characters with valid unicode codepoints. "src" must be null-terminated. - * - * If you are going to use other utf8_to_... functions defined in this header - * with string which may not be valid UTF-8 with valid codepoint (form 0 to - * 0x10FFFF), you should use this function before calling others, since the - * other functions do not check whether the string is valid UTF-8 or not. - * - * If you do not care whether "src" is valid UTF-8 or not, you should use - * strlen() as usual, which should be much faster. - */ -ssize_t utf8_length(const char *src); - -/** - * Measure the length of a UTF-32 string. - */ -size_t utf8_to_utf32_length(const char *src, size_t src_len); - -/** - * Stores a UTF-32 string converted from "src" in "dst". "dst" must be large - * enough to store the entire converted string as measured by - * utf8_to_utf32_length plus space for a NULL terminator. - */ -void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst); - -/** - * Returns the UTF-16 length of UTF-8 string "src". - */ -ssize_t utf8_to_utf16_length(const uint8_t* src, size_t srcLen); - -/** - * Convert UTF-8 to UTF-16 including surrogate pairs. - * Returns a pointer to the end of the string (where a null terminator might go - * if you wanted to add one). - */ -char16_t* utf8_to_utf16_no_null_terminator(const uint8_t* src, size_t srcLen, char16_t* dst); - -/** - * Convert UTF-8 to UTF-16 including surrogate pairs. The destination buffer - * must be large enough to hold the result as measured by utf8_to_utf16_length - * plus an added NULL terminator. - */ -void utf8_to_utf16(const uint8_t* src, size_t srcLen, char16_t* dst); - -} - -#endif diff --git a/include/utils/UniquePtr.h b/include/utils/UniquePtr.h deleted file mode 100644 index bc62fe6..0000000 --- a/include/utils/UniquePtr.h +++ /dev/null @@ -1,239 +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. - */ - -/* === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === - * - * THIS IS A COPY OF libcore/include/UniquePtr.h AND AS SUCH THAT IS THE - * CANONICAL SOURCE OF THIS FILE. PLEASE KEEP THEM IN SYNC. - * - * === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === - */ - -#ifndef UNIQUE_PTR_H_included -#define UNIQUE_PTR_H_included - -#include <cstdlib> // For NULL. - -// Default deleter for pointer types. -template <typename T> -struct DefaultDelete { - enum { type_must_be_complete = sizeof(T) }; - DefaultDelete() {} - void operator()(T* p) const { - delete p; - } -}; - -// Default deleter for array types. -template <typename T> -struct DefaultDelete<T[]> { - enum { type_must_be_complete = sizeof(T) }; - void operator()(T* p) const { - delete[] p; - } -}; - -// A smart pointer that deletes the given pointer on destruction. -// Equivalent to C++0x's std::unique_ptr (a combination of boost::scoped_ptr -// and boost::scoped_array). -// Named to be in keeping with Android style but also to avoid -// collision with any other implementation, until we can switch over -// to unique_ptr. -// Use thus: -// UniquePtr<C> c(new C); -template <typename T, typename D = DefaultDelete<T> > -class UniquePtr { -public: - // Construct a new UniquePtr, taking ownership of the given raw pointer. - explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) { - } - - ~UniquePtr() { - reset(); - } - - // Accessors. - T& operator*() const { return *mPtr; } - T* operator->() const { return mPtr; } - T* get() const { return mPtr; } - - // Returns the raw pointer and hands over ownership to the caller. - // The pointer will not be deleted by UniquePtr. - T* release() __attribute__((warn_unused_result)) { - T* result = mPtr; - mPtr = NULL; - return result; - } - - // Takes ownership of the given raw pointer. - // If this smart pointer previously owned a different raw pointer, that - // raw pointer will be freed. - void reset(T* ptr = NULL) { - if (ptr != mPtr) { - D()(mPtr); - mPtr = ptr; - } - } - -private: - // The raw pointer. - T* mPtr; - - // Comparing unique pointers is probably a mistake, since they're unique. - template <typename T2> bool operator==(const UniquePtr<T2>& p) const; - template <typename T2> bool operator!=(const UniquePtr<T2>& p) const; - - // Disallow copy and assignment. - UniquePtr(const UniquePtr&); - void operator=(const UniquePtr&); -}; - -// Partial specialization for array types. Like std::unique_ptr, this removes -// operator* and operator-> but adds operator[]. -template <typename T, typename D> -class UniquePtr<T[], D> { -public: - explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) { - } - - ~UniquePtr() { - reset(); - } - - T& operator[](size_t i) const { - return mPtr[i]; - } - T* get() const { return mPtr; } - - T* release() __attribute__((warn_unused_result)) { - T* result = mPtr; - mPtr = NULL; - return result; - } - - void reset(T* ptr = NULL) { - if (ptr != mPtr) { - D()(mPtr); - mPtr = ptr; - } - } - -private: - T* mPtr; - - // Disallow copy and assignment. - UniquePtr(const UniquePtr&); - void operator=(const UniquePtr&); -}; - -#if UNIQUE_PTR_TESTS - -// Run these tests with: -// g++ -g -DUNIQUE_PTR_TESTS -x c++ UniquePtr.h && ./a.out - -#include <stdio.h> - -static void assert(bool b) { - if (!b) { - fprintf(stderr, "FAIL\n"); - abort(); - } - fprintf(stderr, "OK\n"); -} -static int cCount = 0; -struct C { - C() { ++cCount; } - ~C() { --cCount; } -}; -static bool freed = false; -struct Freer { - void operator()(int* p) { - assert(*p == 123); - free(p); - freed = true; - } -}; - -int main(int argc, char* argv[]) { - // - // UniquePtr<T> tests... - // - - // Can we free a single object? - { - UniquePtr<C> c(new C); - assert(cCount == 1); - } - assert(cCount == 0); - // Does release work? - C* rawC; - { - UniquePtr<C> c(new C); - assert(cCount == 1); - rawC = c.release(); - } - assert(cCount == 1); - delete rawC; - // Does reset work? - { - UniquePtr<C> c(new C); - assert(cCount == 1); - c.reset(new C); - assert(cCount == 1); - } - assert(cCount == 0); - - // - // UniquePtr<T[]> tests... - // - - // Can we free an array? - { - UniquePtr<C[]> cs(new C[4]); - assert(cCount == 4); - } - assert(cCount == 0); - // Does release work? - { - UniquePtr<C[]> c(new C[4]); - assert(cCount == 4); - rawC = c.release(); - } - assert(cCount == 4); - delete[] rawC; - // Does reset work? - { - UniquePtr<C[]> c(new C[4]); - assert(cCount == 4); - c.reset(new C[2]); - assert(cCount == 2); - } - assert(cCount == 0); - - // - // Custom deleter tests... - // - assert(!freed); - { - UniquePtr<int, Freer> i(reinterpret_cast<int*>(malloc(sizeof(int)))); - *i = 123; - } - assert(freed); - return 0; -} -#endif - -#endif // UNIQUE_PTR_H_included diff --git a/include/utils/Vector.h b/include/utils/Vector.h deleted file mode 100644 index ed7b725..0000000 --- a/include/utils/Vector.h +++ /dev/null @@ -1,423 +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_VECTOR_H -#define ANDROID_VECTOR_H - -#include <new> -#include <stdint.h> -#include <sys/types.h> - -#include <cutils/log.h> - -#include <utils/VectorImpl.h> -#include <utils/TypeHelpers.h> - -// --------------------------------------------------------------------------- - -namespace android { - -template <typename TYPE> -class SortedVector; - -/*! - * The main templated vector class ensuring type safety - * while making use of VectorImpl. - * This is the class users want to use. - */ - -template <class TYPE> -class Vector : private VectorImpl -{ -public: - typedef TYPE value_type; - - /*! - * Constructors and destructors - */ - - Vector(); - Vector(const Vector<TYPE>& rhs); - explicit Vector(const SortedVector<TYPE>& rhs); - virtual ~Vector(); - - /*! copy operator */ - const Vector<TYPE>& operator = (const Vector<TYPE>& rhs) const; - Vector<TYPE>& operator = (const Vector<TYPE>& rhs); - - const Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const; - Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs); - - /* - * empty the vector - */ - - inline void clear() { VectorImpl::clear(); } - - /*! - * vector stats - */ - - //! returns number of items in the vector - inline size_t size() const { return VectorImpl::size(); } - //! returns whether or not the vector is empty - inline bool isEmpty() const { return VectorImpl::isEmpty(); } - //! returns how many items can be stored without reallocating the backing store - inline size_t capacity() const { return VectorImpl::capacity(); } - //! sets the capacity. capacity can never be reduced less than size() - inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); } - - /*! - * set the size of the vector. items are appended with the default - * constructor, or removed from the end as needed. - */ - inline ssize_t resize(size_t size) { return VectorImpl::resize(size); } - - /*! - * C-style array access - */ - - //! read-only C-style access - inline const TYPE* array() const; - //! read-write C-style access - TYPE* editArray(); - - /*! - * accessors - */ - - //! read-only access to an item at a given index - inline const TYPE& operator [] (size_t index) const; - //! alternate name for operator [] - inline const TYPE& itemAt(size_t index) const; - //! stack-usage of the vector. returns the top of the stack (last element) - const TYPE& top() const; - - /*! - * modifying the array - */ - - //! copy-on write support, grants write access to an item - TYPE& editItemAt(size_t index); - //! grants right access to the top of the stack (last element) - TYPE& editTop(); - - /*! - * append/insert another vector - */ - - //! insert another vector at a given index - ssize_t insertVectorAt(const Vector<TYPE>& vector, size_t index); - - //! append another vector at the end of this one - ssize_t appendVector(const Vector<TYPE>& vector); - - - //! insert an array at a given index - ssize_t insertArrayAt(const TYPE* array, size_t index, size_t length); - - //! append an array at the end of this vector - ssize_t appendArray(const TYPE* array, size_t length); - - /*! - * add/insert/replace items - */ - - //! insert one or several items initialized with their default constructor - inline ssize_t insertAt(size_t index, size_t numItems = 1); - //! insert one or several items initialized from a prototype item - ssize_t insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1); - //! pop the top of the stack (removes the last element). No-op if the stack's empty - inline void pop(); - //! pushes an item initialized with its default constructor - inline void push(); - //! pushes an item on the top of the stack - void push(const TYPE& item); - //! same as push() but returns the index the item was added at (or an error) - inline ssize_t add(); - //! same as push() but returns the index the item was added at (or an error) - ssize_t add(const TYPE& item); - //! replace an item with a new one initialized with its default constructor - inline ssize_t replaceAt(size_t index); - //! replace an item with a new one - ssize_t replaceAt(const TYPE& item, size_t index); - - /*! - * remove items - */ - - //! remove several items - inline ssize_t removeItemsAt(size_t index, size_t count = 1); - //! remove one item - inline ssize_t removeAt(size_t index) { return removeItemsAt(index); } - - /*! - * sort (stable) the array - */ - - typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs); - typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state); - - inline status_t sort(compar_t cmp); - inline status_t sort(compar_r_t cmp, void* state); - - // for debugging only - inline size_t getItemSize() const { return itemSize(); } - - - /* - * these inlines add some level of compatibility with STL. eventually - * we should probably turn things around. - */ - typedef TYPE* iterator; - typedef TYPE const* const_iterator; - - inline iterator begin() { return editArray(); } - inline iterator end() { return editArray() + size(); } - inline const_iterator begin() const { return array(); } - inline const_iterator end() const { return array() + size(); } - inline void reserve(size_t n) { setCapacity(n); } - inline bool empty() const{ return isEmpty(); } - inline void push_back(const TYPE& item) { insertAt(item, size(), 1); } - inline void push_front(const TYPE& item) { insertAt(item, 0, 1); } - inline iterator erase(iterator pos) { - ssize_t index = removeItemsAt(pos-array()); - return begin() + index; - } - -protected: - virtual void do_construct(void* storage, size_t num) const; - virtual void do_destroy(void* storage, size_t num) const; - virtual void do_copy(void* dest, const void* from, size_t num) const; - virtual void do_splat(void* dest, const void* item, size_t num) const; - virtual void do_move_forward(void* dest, const void* from, size_t num) const; - virtual void do_move_backward(void* dest, const void* from, size_t num) const; -}; - -// Vector<T> can be trivially moved using memcpy() because moving does not -// require any change to the underlying SharedBuffer contents or reference count. -template<typename T> struct trait_trivial_move<Vector<T> > { enum { value = true }; }; - -// --------------------------------------------------------------------------- -// No user serviceable parts from here... -// --------------------------------------------------------------------------- - -template<class TYPE> inline -Vector<TYPE>::Vector() - : VectorImpl(sizeof(TYPE), - ((traits<TYPE>::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) - |(traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) - |(traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0)) - ) -{ -} - -template<class TYPE> inline -Vector<TYPE>::Vector(const Vector<TYPE>& rhs) - : VectorImpl(rhs) { -} - -template<class TYPE> inline -Vector<TYPE>::Vector(const SortedVector<TYPE>& rhs) - : VectorImpl(static_cast<const VectorImpl&>(rhs)) { -} - -template<class TYPE> inline -Vector<TYPE>::~Vector() { - finish_vector(); -} - -template<class TYPE> inline -Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) { - VectorImpl::operator = (rhs); - return *this; -} - -template<class TYPE> inline -const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const { - VectorImpl::operator = (static_cast<const VectorImpl&>(rhs)); - return *this; -} - -template<class TYPE> inline -Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) { - VectorImpl::operator = (static_cast<const VectorImpl&>(rhs)); - return *this; -} - -template<class TYPE> inline -const Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const { - VectorImpl::operator = (rhs); - return *this; -} - -template<class TYPE> inline -const TYPE* Vector<TYPE>::array() const { - return static_cast<const TYPE *>(arrayImpl()); -} - -template<class TYPE> inline -TYPE* Vector<TYPE>::editArray() { - return static_cast<TYPE *>(editArrayImpl()); -} - - -template<class TYPE> inline -const TYPE& Vector<TYPE>::operator[](size_t index) const { - LOG_FATAL_IF(index>=size(), - "%s: index=%u out of range (%u)", __PRETTY_FUNCTION__, - int(index), int(size())); - return *(array() + index); -} - -template<class TYPE> inline -const TYPE& Vector<TYPE>::itemAt(size_t index) const { - return operator[](index); -} - -template<class TYPE> inline -const TYPE& Vector<TYPE>::top() const { - return *(array() + size() - 1); -} - -template<class TYPE> inline -TYPE& Vector<TYPE>::editItemAt(size_t index) { - return *( static_cast<TYPE *>(editItemLocation(index)) ); -} - -template<class TYPE> inline -TYPE& Vector<TYPE>::editTop() { - return *( static_cast<TYPE *>(editItemLocation(size()-1)) ); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::insertVectorAt(const Vector<TYPE>& vector, size_t index) { - return VectorImpl::insertVectorAt(reinterpret_cast<const VectorImpl&>(vector), index); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::appendVector(const Vector<TYPE>& vector) { - return VectorImpl::appendVector(reinterpret_cast<const VectorImpl&>(vector)); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::insertArrayAt(const TYPE* array, size_t index, size_t length) { - return VectorImpl::insertArrayAt(array, index, length); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::appendArray(const TYPE* array, size_t length) { - return VectorImpl::appendArray(array, length); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) { - return VectorImpl::insertAt(&item, index, numItems); -} - -template<class TYPE> inline -void Vector<TYPE>::push(const TYPE& item) { - return VectorImpl::push(&item); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::add(const TYPE& item) { - return VectorImpl::add(&item); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::replaceAt(const TYPE& item, size_t index) { - return VectorImpl::replaceAt(&item, index); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::insertAt(size_t index, size_t numItems) { - return VectorImpl::insertAt(index, numItems); -} - -template<class TYPE> inline -void Vector<TYPE>::pop() { - VectorImpl::pop(); -} - -template<class TYPE> inline -void Vector<TYPE>::push() { - VectorImpl::push(); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::add() { - return VectorImpl::add(); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::replaceAt(size_t index) { - return VectorImpl::replaceAt(index); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) { - return VectorImpl::removeItemsAt(index, count); -} - -template<class TYPE> inline -status_t Vector<TYPE>::sort(Vector<TYPE>::compar_t cmp) { - return VectorImpl::sort((VectorImpl::compar_t)cmp); -} - -template<class TYPE> inline -status_t Vector<TYPE>::sort(Vector<TYPE>::compar_r_t cmp, void* state) { - return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state); -} - -// --------------------------------------------------------------------------- - -template<class TYPE> -void Vector<TYPE>::do_construct(void* storage, size_t num) const { - construct_type( reinterpret_cast<TYPE*>(storage), num ); -} - -template<class TYPE> -void Vector<TYPE>::do_destroy(void* storage, size_t num) const { - destroy_type( reinterpret_cast<TYPE*>(storage), num ); -} - -template<class TYPE> -void Vector<TYPE>::do_copy(void* dest, const void* from, size_t num) const { - copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); -} - -template<class TYPE> -void Vector<TYPE>::do_splat(void* dest, const void* item, size_t num) const { - splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num ); -} - -template<class TYPE> -void Vector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const { - move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); -} - -template<class TYPE> -void Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const { - move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); -} - -}; // namespace android - - -// --------------------------------------------------------------------------- - -#endif // ANDROID_VECTOR_H diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h deleted file mode 100644 index 21ad71c..0000000 --- a/include/utils/VectorImpl.h +++ /dev/null @@ -1,183 +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_VECTOR_IMPL_H -#define ANDROID_VECTOR_IMPL_H - -#include <assert.h> -#include <stdint.h> -#include <sys/types.h> -#include <utils/Errors.h> - -// --------------------------------------------------------------------------- -// No user serviceable parts in here... -// --------------------------------------------------------------------------- - -namespace android { - -/*! - * Implementation of the guts of the vector<> class - * this ensures backward binary compatibility and - * reduces code size. - * For performance reasons, we expose mStorage and mCount - * so these fields are set in stone. - * - */ - -class VectorImpl -{ -public: - enum { // flags passed to the ctor - HAS_TRIVIAL_CTOR = 0x00000001, - HAS_TRIVIAL_DTOR = 0x00000002, - HAS_TRIVIAL_COPY = 0x00000004, - }; - - VectorImpl(size_t itemSize, uint32_t flags); - VectorImpl(const VectorImpl& rhs); - virtual ~VectorImpl(); - - /*! must be called from subclasses destructor */ - void finish_vector(); - - VectorImpl& operator = (const VectorImpl& rhs); - - /*! C-style array access */ - inline const void* arrayImpl() const { return mStorage; } - void* editArrayImpl(); - - /*! vector stats */ - inline size_t size() const { return mCount; } - inline bool isEmpty() const { return mCount == 0; } - size_t capacity() const; - ssize_t setCapacity(size_t size); - ssize_t resize(size_t size); - - /*! append/insert another vector or array */ - ssize_t insertVectorAt(const VectorImpl& vector, size_t index); - ssize_t appendVector(const VectorImpl& vector); - ssize_t insertArrayAt(const void* array, size_t index, size_t length); - ssize_t appendArray(const void* array, size_t length); - - /*! add/insert/replace items */ - ssize_t insertAt(size_t where, size_t numItems = 1); - ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); - void pop(); - void push(); - void push(const void* item); - ssize_t add(); - ssize_t add(const void* item); - ssize_t replaceAt(size_t index); - ssize_t replaceAt(const void* item, size_t index); - - /*! remove items */ - ssize_t removeItemsAt(size_t index, size_t count = 1); - void clear(); - - const void* itemLocation(size_t index) const; - void* editItemLocation(size_t index); - - typedef int (*compar_t)(const void* lhs, const void* rhs); - typedef int (*compar_r_t)(const void* lhs, const void* rhs, void* state); - status_t sort(compar_t cmp); - status_t sort(compar_r_t cmp, void* state); - -protected: - size_t itemSize() const; - void release_storage(); - - virtual void do_construct(void* storage, size_t num) const = 0; - virtual void do_destroy(void* storage, size_t num) const = 0; - virtual void do_copy(void* dest, const void* from, size_t num) const = 0; - virtual void do_splat(void* dest, const void* item, size_t num) const = 0; - virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0; - virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0; - -private: - void* _grow(size_t where, size_t amount); - void _shrink(size_t where, size_t amount); - - inline void _do_construct(void* storage, size_t num) const; - inline void _do_destroy(void* storage, size_t num) const; - inline void _do_copy(void* dest, const void* from, size_t num) const; - inline void _do_splat(void* dest, const void* item, size_t num) const; - inline void _do_move_forward(void* dest, const void* from, size_t num) const; - inline void _do_move_backward(void* dest, const void* from, size_t num) const; - - // These 2 fields are exposed in the inlines below, - // so they're set in stone. - void * mStorage; // base address of the vector - size_t mCount; // number of items - - const uint32_t mFlags; - const size_t mItemSize; -}; - - - -class SortedVectorImpl : public VectorImpl -{ -public: - SortedVectorImpl(size_t itemSize, uint32_t flags); - SortedVectorImpl(const VectorImpl& rhs); - virtual ~SortedVectorImpl(); - - SortedVectorImpl& operator = (const SortedVectorImpl& rhs); - - //! finds the index of an item - ssize_t indexOf(const void* item) const; - - //! finds where this item should be inserted - size_t orderOf(const void* item) const; - - //! add an item in the right place (or replaces it if there is one) - ssize_t add(const void* item); - - //! merges a vector into this one - ssize_t merge(const VectorImpl& vector); - ssize_t merge(const SortedVectorImpl& vector); - - //! removes an item - ssize_t remove(const void* item); - -protected: - virtual int do_compare(const void* lhs, const void* rhs) const = 0; - -private: - ssize_t _indexOrderOf(const void* item, size_t* order = 0) const; - - // these are made private, because they can't be used on a SortedVector - // (they don't have an implementation either) - ssize_t add(); - void pop(); - void push(); - void push(const void* item); - ssize_t insertVectorAt(const VectorImpl& vector, size_t index); - ssize_t appendVector(const VectorImpl& vector); - ssize_t insertArrayAt(const void* array, size_t index, size_t length); - ssize_t appendArray(const void* array, size_t length); - ssize_t insertAt(size_t where, size_t numItems = 1); - ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); - ssize_t replaceAt(size_t index); - ssize_t replaceAt(const void* item, size_t index); -}; - -}; // namespace android - - -// --------------------------------------------------------------------------- - -#endif // ANDROID_VECTOR_IMPL_H diff --git a/include/utils/ashmem.h b/include/utils/ashmem.h deleted file mode 100644 index 0854775..0000000 --- a/include/utils/ashmem.h +++ /dev/null @@ -1,41 +0,0 @@ -/* utils/ashmem.h - ** - ** Copyright 2008 The Android Open Source Project - ** - ** This file is dual licensed. It may be redistributed and/or modified - ** under the terms of the Apache 2.0 License OR version 2 of the GNU - ** General Public License. - */ - -#ifndef _UTILS_ASHMEM_H -#define _UTILS_ASHMEM_H - -#include <linux/limits.h> -#include <linux/ioctl.h> - -#define ASHMEM_NAME_LEN 256 - -#define ASHMEM_NAME_DEF "dev/ashmem" - -/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */ -#define ASHMEM_NOT_REAPED 0 -#define ASHMEM_WAS_REAPED 1 - -/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */ -#define ASHMEM_NOW_UNPINNED 0 -#define ASHMEM_NOW_PINNED 1 - -#define __ASHMEMIOC 0x77 - -#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN]) -#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN]) -#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t) -#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4) -#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long) -#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6) -#define ASHMEM_PIN _IO(__ASHMEMIOC, 7) -#define ASHMEM_UNPIN _IO(__ASHMEMIOC, 8) -#define ASHMEM_ISPINNED _IO(__ASHMEMIOC, 9) -#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10) - -#endif /* _UTILS_ASHMEM_H */ diff --git a/include/utils/misc.h b/include/utils/misc.h deleted file mode 100644 index 6cccec3..0000000 --- a/include/utils/misc.h +++ /dev/null @@ -1,38 +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. - */ - -// -// Handy utility functions and portability code. -// -#ifndef _LIBS_UTILS_MISC_H -#define _LIBS_UTILS_MISC_H - -#include <utils/Endian.h> - -/* get #of elements in a static array */ -#ifndef NELEM -# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) -#endif - -namespace android { - -typedef void (*sysprop_change_callback)(void); -void add_sysprop_change_callback(sysprop_change_callback cb, int priority); -void report_sysprop_change(); - -}; // namespace android - -#endif // _LIBS_UTILS_MISC_H diff --git a/include/utils/threads.h b/include/utils/threads.h deleted file mode 100644 index 9de3382..0000000 --- a/include/utils/threads.h +++ /dev/null @@ -1,38 +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 _LIBS_UTILS_THREADS_H -#define _LIBS_UTILS_THREADS_H - -/* - * Please, DO NOT USE! - * - * This file is here only for legacy reasons. Instead, include directly - * the headers you need below. - * - */ - -#include <utils/AndroidThreads.h> - -#ifdef __cplusplus -#include <utils/Condition.h> -#include <utils/Errors.h> -#include <utils/Mutex.h> -#include <utils/RWLock.h> -#include <utils/Thread.h> -#endif - -#endif // _LIBS_UTILS_THREADS_H diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk deleted file mode 100644 index 7e6b1be..0000000 --- a/libs/utils/Android.mk +++ /dev/null @@ -1,144 +0,0 @@ -# Copyright (C) 2008 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. - -LOCAL_PATH:= $(call my-dir) - -# libutils is a little unique: It's built twice, once for the host -# and once for the device. - -commonSources:= \ - BasicHashtable.cpp \ - BlobCache.cpp \ - CallStack.cpp \ - FileMap.cpp \ - JenkinsHash.cpp \ - LinearAllocator.cpp \ - LinearTransform.cpp \ - Log.cpp \ - PropertyMap.cpp \ - RefBase.cpp \ - SharedBuffer.cpp \ - Static.cpp \ - StopWatch.cpp \ - String8.cpp \ - String16.cpp \ - SystemClock.cpp \ - Threads.cpp \ - Timers.cpp \ - Tokenizer.cpp \ - Unicode.cpp \ - VectorImpl.cpp \ - misc.cpp - -host_commonCflags := -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS) - -ifeq ($(HOST_OS),windows) -ifeq ($(strip $(USE_CYGWIN),),) -# Under MinGW, ctype.h doesn't need multi-byte support -host_commonCflags += -DMB_CUR_MAX=1 -endif -endif - -host_commonLdlibs := - -ifeq ($(TARGET_OS),linux) -host_commonLdlibs += -lrt -ldl -endif - - -# For the host -# ===================================================== -include $(CLEAR_VARS) -LOCAL_SRC_FILES:= $(commonSources) -ifeq ($(HOST_OS), linux) -LOCAL_SRC_FILES += Looper.cpp -endif -LOCAL_MODULE:= libutils -LOCAL_STATIC_LIBRARIES := liblog -LOCAL_CFLAGS += $(host_commonCflags) -LOCAL_LDLIBS += $(host_commonLdlibs) -include $(BUILD_HOST_STATIC_LIBRARY) - - -# For the host, 64-bit -# ===================================================== -include $(CLEAR_VARS) -LOCAL_SRC_FILES:= $(commonSources) -ifeq ($(HOST_OS), linux) -LOCAL_SRC_FILES += Looper.cpp -endif -LOCAL_MODULE:= lib64utils -LOCAL_STATIC_LIBRARIES := liblog -LOCAL_CFLAGS += $(host_commonCflags) -m64 -LOCAL_LDLIBS += $(host_commonLdlibs) -include $(BUILD_HOST_STATIC_LIBRARY) - - -# For the device, static -# ===================================================== -include $(CLEAR_VARS) - - -# we have the common sources, plus some device-specific stuff -LOCAL_SRC_FILES:= \ - $(commonSources) \ - Looper.cpp \ - Trace.cpp - -ifeq ($(TARGET_OS),linux) -LOCAL_LDLIBS += -lrt -ldl -endif - -ifeq ($(TARGET_ARCH),mips) -LOCAL_CFLAGS += -DALIGN_DOUBLE -endif - -LOCAL_C_INCLUDES += \ - bionic/libc/private \ - external/zlib - -LOCAL_LDLIBS += -lpthread - -LOCAL_STATIC_LIBRARIES := \ - libcutils - -LOCAL_SHARED_LIBRARIES := \ - libcorkscrew \ - liblog \ - libdl - -LOCAL_MODULE:= libutils -include $(BUILD_STATIC_LIBRARY) - -# For the device, shared -# ===================================================== -include $(CLEAR_VARS) -LOCAL_MODULE:= libutils -LOCAL_WHOLE_STATIC_LIBRARIES := libutils -LOCAL_SHARED_LIBRARIES := \ - liblog \ - libcutils \ - libdl \ - libcorkscrew - -include $(BUILD_SHARED_LIBRARY) - -# Include subdirectory makefiles -# ============================================================ - -# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework -# team really wants is to build the stuff defined by this makefile. -ifeq (,$(ONE_SHOT_MAKEFILE)) -include $(call first-makefiles-under,$(LOCAL_PATH)) -endif diff --git a/libs/utils/BasicHashtable.cpp b/libs/utils/BasicHashtable.cpp deleted file mode 100644 index 491d9e9..0000000 --- a/libs/utils/BasicHashtable.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (C) 2011 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 "BasicHashtable" - -#include <math.h> - -#include <utils/Log.h> -#include <utils/BasicHashtable.h> -#include <utils/misc.h> - -namespace android { - -BasicHashtableImpl::BasicHashtableImpl(size_t entrySize, bool hasTrivialDestructor, - size_t minimumInitialCapacity, float loadFactor) : - mBucketSize(entrySize + sizeof(Bucket)), mHasTrivialDestructor(hasTrivialDestructor), - mLoadFactor(loadFactor), mSize(0), - mFilledBuckets(0), mBuckets(NULL) { - determineCapacity(minimumInitialCapacity, mLoadFactor, &mBucketCount, &mCapacity); -} - -BasicHashtableImpl::BasicHashtableImpl(const BasicHashtableImpl& other) : - mBucketSize(other.mBucketSize), mHasTrivialDestructor(other.mHasTrivialDestructor), - mCapacity(other.mCapacity), mLoadFactor(other.mLoadFactor), - mSize(other.mSize), mFilledBuckets(other.mFilledBuckets), - mBucketCount(other.mBucketCount), mBuckets(other.mBuckets) { - if (mBuckets) { - SharedBuffer::bufferFromData(mBuckets)->acquire(); - } -} - -BasicHashtableImpl::~BasicHashtableImpl() -{ -} - -void BasicHashtableImpl::dispose() { - if (mBuckets) { - releaseBuckets(mBuckets, mBucketCount); - } -} - -void BasicHashtableImpl::clone() { - if (mBuckets) { - void* newBuckets = allocateBuckets(mBucketCount); - copyBuckets(mBuckets, newBuckets, mBucketCount); - releaseBuckets(mBuckets, mBucketCount); - mBuckets = newBuckets; - } -} - -void BasicHashtableImpl::setTo(const BasicHashtableImpl& other) { - if (mBuckets) { - releaseBuckets(mBuckets, mBucketCount); - } - - mCapacity = other.mCapacity; - mLoadFactor = other.mLoadFactor; - mSize = other.mSize; - mFilledBuckets = other.mFilledBuckets; - mBucketCount = other.mBucketCount; - mBuckets = other.mBuckets; - - if (mBuckets) { - SharedBuffer::bufferFromData(mBuckets)->acquire(); - } -} - -void BasicHashtableImpl::clear() { - if (mBuckets) { - if (mFilledBuckets) { - SharedBuffer* sb = SharedBuffer::bufferFromData(mBuckets); - if (sb->onlyOwner()) { - destroyBuckets(mBuckets, mBucketCount); - for (size_t i = 0; i < mBucketCount; i++) { - Bucket& bucket = bucketAt(mBuckets, i); - bucket.cookie = 0; - } - } else { - releaseBuckets(mBuckets, mBucketCount); - mBuckets = NULL; - } - mFilledBuckets = 0; - } - mSize = 0; - } -} - -ssize_t BasicHashtableImpl::next(ssize_t index) const { - if (mSize) { - while (size_t(++index) < mBucketCount) { - const Bucket& bucket = bucketAt(mBuckets, index); - if (bucket.cookie & Bucket::PRESENT) { - return index; - } - } - } - return -1; -} - -ssize_t BasicHashtableImpl::find(ssize_t index, hash_t hash, - const void* __restrict__ key) const { - if (!mSize) { - return -1; - } - - hash = trimHash(hash); - if (index < 0) { - index = chainStart(hash, mBucketCount); - - const Bucket& bucket = bucketAt(mBuckets, size_t(index)); - if (bucket.cookie & Bucket::PRESENT) { - if (compareBucketKey(bucket, key)) { - return index; - } - } else { - if (!(bucket.cookie & Bucket::COLLISION)) { - return -1; - } - } - } - - size_t inc = chainIncrement(hash, mBucketCount); - for (;;) { - index = chainSeek(index, inc, mBucketCount); - - const Bucket& bucket = bucketAt(mBuckets, size_t(index)); - if (bucket.cookie & Bucket::PRESENT) { - if ((bucket.cookie & Bucket::HASH_MASK) == hash - && compareBucketKey(bucket, key)) { - return index; - } - } - if (!(bucket.cookie & Bucket::COLLISION)) { - return -1; - } - } -} - -size_t BasicHashtableImpl::add(hash_t hash, const void* entry) { - if (!mBuckets) { - mBuckets = allocateBuckets(mBucketCount); - } else { - edit(); - } - - hash = trimHash(hash); - for (;;) { - size_t index = chainStart(hash, mBucketCount); - Bucket* bucket = &bucketAt(mBuckets, size_t(index)); - if (bucket->cookie & Bucket::PRESENT) { - size_t inc = chainIncrement(hash, mBucketCount); - do { - bucket->cookie |= Bucket::COLLISION; - index = chainSeek(index, inc, mBucketCount); - bucket = &bucketAt(mBuckets, size_t(index)); - } while (bucket->cookie & Bucket::PRESENT); - } - - uint32_t collision = bucket->cookie & Bucket::COLLISION; - if (!collision) { - if (mFilledBuckets >= mCapacity) { - rehash(mCapacity * 2, mLoadFactor); - continue; - } - mFilledBuckets += 1; - } - - bucket->cookie = collision | Bucket::PRESENT | hash; - mSize += 1; - initializeBucketEntry(*bucket, entry); - return index; - } -} - -void BasicHashtableImpl::removeAt(size_t index) { - edit(); - - Bucket& bucket = bucketAt(mBuckets, index); - bucket.cookie &= ~Bucket::PRESENT; - if (!(bucket.cookie & Bucket::COLLISION)) { - mFilledBuckets -= 1; - } - mSize -= 1; - if (!mHasTrivialDestructor) { - destroyBucketEntry(bucket); - } -} - -void BasicHashtableImpl::rehash(size_t minimumCapacity, float loadFactor) { - if (minimumCapacity < mSize) { - minimumCapacity = mSize; - } - size_t newBucketCount, newCapacity; - determineCapacity(minimumCapacity, loadFactor, &newBucketCount, &newCapacity); - - if (newBucketCount != mBucketCount || newCapacity != mCapacity) { - if (mBuckets) { - void* newBuckets; - if (mSize) { - newBuckets = allocateBuckets(newBucketCount); - for (size_t i = 0; i < mBucketCount; i++) { - const Bucket& fromBucket = bucketAt(mBuckets, i); - if (fromBucket.cookie & Bucket::PRESENT) { - hash_t hash = fromBucket.cookie & Bucket::HASH_MASK; - size_t index = chainStart(hash, newBucketCount); - Bucket* toBucket = &bucketAt(newBuckets, size_t(index)); - if (toBucket->cookie & Bucket::PRESENT) { - size_t inc = chainIncrement(hash, newBucketCount); - do { - toBucket->cookie |= Bucket::COLLISION; - index = chainSeek(index, inc, newBucketCount); - toBucket = &bucketAt(newBuckets, size_t(index)); - } while (toBucket->cookie & Bucket::PRESENT); - } - toBucket->cookie = Bucket::PRESENT | hash; - initializeBucketEntry(*toBucket, fromBucket.entry); - } - } - } else { - newBuckets = NULL; - } - releaseBuckets(mBuckets, mBucketCount); - mBuckets = newBuckets; - mFilledBuckets = mSize; - } - mBucketCount = newBucketCount; - mCapacity = newCapacity; - } - mLoadFactor = loadFactor; -} - -void* BasicHashtableImpl::allocateBuckets(size_t count) const { - size_t bytes = count * mBucketSize; - SharedBuffer* sb = SharedBuffer::alloc(bytes); - LOG_ALWAYS_FATAL_IF(!sb, "Could not allocate %u bytes for hashtable with %u buckets.", - uint32_t(bytes), uint32_t(count)); - void* buckets = sb->data(); - for (size_t i = 0; i < count; i++) { - Bucket& bucket = bucketAt(buckets, i); - bucket.cookie = 0; - } - return buckets; -} - -void BasicHashtableImpl::releaseBuckets(void* __restrict__ buckets, size_t count) const { - SharedBuffer* sb = SharedBuffer::bufferFromData(buckets); - if (sb->release(SharedBuffer::eKeepStorage) == 1) { - destroyBuckets(buckets, count); - SharedBuffer::dealloc(sb); - } -} - -void BasicHashtableImpl::destroyBuckets(void* __restrict__ buckets, size_t count) const { - if (!mHasTrivialDestructor) { - for (size_t i = 0; i < count; i++) { - Bucket& bucket = bucketAt(buckets, i); - if (bucket.cookie & Bucket::PRESENT) { - destroyBucketEntry(bucket); - } - } - } -} - -void BasicHashtableImpl::copyBuckets(const void* __restrict__ fromBuckets, - void* __restrict__ toBuckets, size_t count) const { - for (size_t i = 0; i < count; i++) { - const Bucket& fromBucket = bucketAt(fromBuckets, i); - Bucket& toBucket = bucketAt(toBuckets, i); - toBucket.cookie = fromBucket.cookie; - if (fromBucket.cookie & Bucket::PRESENT) { - initializeBucketEntry(toBucket, fromBucket.entry); - } - } -} - -// Table of 31-bit primes where each prime is no less than twice as large -// as the previous one. Generated by "primes.py". -static size_t PRIMES[] = { - 5, - 11, - 23, - 47, - 97, - 197, - 397, - 797, - 1597, - 3203, - 6421, - 12853, - 25717, - 51437, - 102877, - 205759, - 411527, - 823117, - 1646237, - 3292489, - 6584983, - 13169977, - 26339969, - 52679969, - 105359939, - 210719881, - 421439783, - 842879579, - 1685759167, - 0, -}; - -void BasicHashtableImpl::determineCapacity(size_t minimumCapacity, float loadFactor, - size_t* __restrict__ outBucketCount, size_t* __restrict__ outCapacity) { - LOG_ALWAYS_FATAL_IF(loadFactor <= 0.0f || loadFactor > 1.0f, - "Invalid load factor %0.3f. Must be in the range (0, 1].", loadFactor); - - size_t count = ceilf(minimumCapacity / loadFactor) + 1; - size_t i = 0; - while (count > PRIMES[i] && i < NELEM(PRIMES)) { - i++; - } - count = PRIMES[i]; - LOG_ALWAYS_FATAL_IF(!count, "Could not determine required number of buckets for " - "hashtable with minimum capacity %u and load factor %0.3f.", - uint32_t(minimumCapacity), loadFactor); - *outBucketCount = count; - *outCapacity = ceilf((count - 1) * loadFactor); -} - -}; // namespace android diff --git a/libs/utils/BlobCache.cpp b/libs/utils/BlobCache.cpp deleted file mode 100644 index 0fb1d8e..0000000 --- a/libs/utils/BlobCache.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/* - ** Copyright 2011, 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 "BlobCache" -//#define LOG_NDEBUG 0 - -#include <stdlib.h> -#include <string.h> - -#include <utils/BlobCache.h> -#include <utils/Errors.h> -#include <utils/Log.h> - -namespace android { - -// BlobCache::Header::mMagicNumber value -static const uint32_t blobCacheMagic = '_Bb$'; - -// BlobCache::Header::mBlobCacheVersion value -static const uint32_t blobCacheVersion = 1; - -// BlobCache::Header::mDeviceVersion value -static const uint32_t blobCacheDeviceVersion = 1; - -BlobCache::BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize): - mMaxKeySize(maxKeySize), - mMaxValueSize(maxValueSize), - mMaxTotalSize(maxTotalSize), - mTotalSize(0) { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); -#ifdef _WIN32 - srand(now); -#else - mRandState[0] = (now >> 0) & 0xFFFF; - mRandState[1] = (now >> 16) & 0xFFFF; - mRandState[2] = (now >> 32) & 0xFFFF; -#endif - ALOGV("initializing random seed using %lld", now); -} - -void BlobCache::set(const void* key, size_t keySize, const void* value, - size_t valueSize) { - if (mMaxKeySize < keySize) { - ALOGV("set: not caching because the key is too large: %d (limit: %d)", - keySize, mMaxKeySize); - return; - } - if (mMaxValueSize < valueSize) { - ALOGV("set: not caching because the value is too large: %d (limit: %d)", - valueSize, mMaxValueSize); - return; - } - if (mMaxTotalSize < keySize + valueSize) { - ALOGV("set: not caching because the combined key/value size is too " - "large: %d (limit: %d)", keySize + valueSize, mMaxTotalSize); - return; - } - if (keySize == 0) { - ALOGW("set: not caching because keySize is 0"); - return; - } - if (valueSize <= 0) { - ALOGW("set: not caching because valueSize is 0"); - return; - } - - sp<Blob> dummyKey(new Blob(key, keySize, false)); - CacheEntry dummyEntry(dummyKey, NULL); - - while (true) { - ssize_t index = mCacheEntries.indexOf(dummyEntry); - if (index < 0) { - // Create a new cache entry. - sp<Blob> keyBlob(new Blob(key, keySize, true)); - sp<Blob> valueBlob(new Blob(value, valueSize, true)); - size_t newTotalSize = mTotalSize + keySize + valueSize; - if (mMaxTotalSize < newTotalSize) { - if (isCleanable()) { - // Clean the cache and try again. - clean(); - continue; - } else { - ALOGV("set: not caching new key/value pair because the " - "total cache size limit would be exceeded: %d " - "(limit: %d)", - keySize + valueSize, mMaxTotalSize); - break; - } - } - mCacheEntries.add(CacheEntry(keyBlob, valueBlob)); - mTotalSize = newTotalSize; - ALOGV("set: created new cache entry with %d byte key and %d byte value", - keySize, valueSize); - } else { - // Update the existing cache entry. - sp<Blob> valueBlob(new Blob(value, valueSize, true)); - sp<Blob> oldValueBlob(mCacheEntries[index].getValue()); - size_t newTotalSize = mTotalSize + valueSize - oldValueBlob->getSize(); - if (mMaxTotalSize < newTotalSize) { - if (isCleanable()) { - // Clean the cache and try again. - clean(); - continue; - } else { - ALOGV("set: not caching new value because the total cache " - "size limit would be exceeded: %d (limit: %d)", - keySize + valueSize, mMaxTotalSize); - break; - } - } - mCacheEntries.editItemAt(index).setValue(valueBlob); - mTotalSize = newTotalSize; - ALOGV("set: updated existing cache entry with %d byte key and %d byte " - "value", keySize, valueSize); - } - break; - } -} - -size_t BlobCache::get(const void* key, size_t keySize, void* value, - size_t valueSize) { - if (mMaxKeySize < keySize) { - ALOGV("get: not searching because the key is too large: %d (limit %d)", - keySize, mMaxKeySize); - return 0; - } - sp<Blob> dummyKey(new Blob(key, keySize, false)); - CacheEntry dummyEntry(dummyKey, NULL); - ssize_t index = mCacheEntries.indexOf(dummyEntry); - if (index < 0) { - ALOGV("get: no cache entry found for key of size %d", keySize); - return 0; - } - - // The key was found. Return the value if the caller's buffer is large - // enough. - sp<Blob> valueBlob(mCacheEntries[index].getValue()); - size_t valueBlobSize = valueBlob->getSize(); - if (valueBlobSize <= valueSize) { - ALOGV("get: copying %d bytes to caller's buffer", valueBlobSize); - memcpy(value, valueBlob->getData(), valueBlobSize); - } else { - ALOGV("get: caller's buffer is too small for value: %d (needs %d)", - valueSize, valueBlobSize); - } - return valueBlobSize; -} - -static inline size_t align4(size_t size) { - return (size + 3) & ~3; -} - -size_t BlobCache::getFlattenedSize() const { - size_t size = sizeof(Header); - for (size_t i = 0; i < mCacheEntries.size(); i++) { - const CacheEntry& e(mCacheEntries[i]); - sp<Blob> keyBlob = e.getKey(); - sp<Blob> valueBlob = e.getValue(); - size = align4(size); - size += sizeof(EntryHeader) + keyBlob->getSize() + - valueBlob->getSize(); - } - return size; -} - -status_t BlobCache::flatten(void* buffer, size_t size) const { - // Write the cache header - if (size < sizeof(Header)) { - ALOGE("flatten: not enough room for cache header"); - return BAD_VALUE; - } - Header* header = reinterpret_cast<Header*>(buffer); - header->mMagicNumber = blobCacheMagic; - header->mBlobCacheVersion = blobCacheVersion; - header->mDeviceVersion = blobCacheDeviceVersion; - header->mNumEntries = mCacheEntries.size(); - - // Write cache entries - uint8_t* byteBuffer = reinterpret_cast<uint8_t*>(buffer); - off_t byteOffset = align4(sizeof(Header)); - for (size_t i = 0; i < mCacheEntries.size(); i++) { - const CacheEntry& e(mCacheEntries[i]); - sp<Blob> keyBlob = e.getKey(); - sp<Blob> valueBlob = e.getValue(); - size_t keySize = keyBlob->getSize(); - size_t valueSize = valueBlob->getSize(); - - size_t entrySize = sizeof(EntryHeader) + keySize + valueSize; - if (byteOffset + entrySize > size) { - ALOGE("flatten: not enough room for cache entries"); - return BAD_VALUE; - } - - EntryHeader* eheader = reinterpret_cast<EntryHeader*>( - &byteBuffer[byteOffset]); - eheader->mKeySize = keySize; - eheader->mValueSize = valueSize; - - memcpy(eheader->mData, keyBlob->getData(), keySize); - memcpy(eheader->mData + keySize, valueBlob->getData(), valueSize); - - byteOffset += align4(entrySize); - } - - return OK; -} - -status_t BlobCache::unflatten(void const* buffer, size_t size) { - // All errors should result in the BlobCache being in an empty state. - mCacheEntries.clear(); - - // Read the cache header - if (size < sizeof(Header)) { - ALOGE("unflatten: not enough room for cache header"); - return BAD_VALUE; - } - const Header* header = reinterpret_cast<const Header*>(buffer); - if (header->mMagicNumber != blobCacheMagic) { - ALOGE("unflatten: bad magic number: %d", header->mMagicNumber); - return BAD_VALUE; - } - if (header->mBlobCacheVersion != blobCacheVersion || - header->mDeviceVersion != blobCacheDeviceVersion) { - // We treat version mismatches as an empty cache. - return OK; - } - - // Read cache entries - const uint8_t* byteBuffer = reinterpret_cast<const uint8_t*>(buffer); - off_t byteOffset = align4(sizeof(Header)); - size_t numEntries = header->mNumEntries; - for (size_t i = 0; i < numEntries; i++) { - if (byteOffset + sizeof(EntryHeader) > size) { - mCacheEntries.clear(); - ALOGE("unflatten: not enough room for cache entry headers"); - return BAD_VALUE; - } - - const EntryHeader* eheader = reinterpret_cast<const EntryHeader*>( - &byteBuffer[byteOffset]); - size_t keySize = eheader->mKeySize; - size_t valueSize = eheader->mValueSize; - size_t entrySize = sizeof(EntryHeader) + keySize + valueSize; - - if (byteOffset + entrySize > size) { - mCacheEntries.clear(); - ALOGE("unflatten: not enough room for cache entry headers"); - return BAD_VALUE; - } - - const uint8_t* data = eheader->mData; - set(data, keySize, data + keySize, valueSize); - - byteOffset += align4(entrySize); - } - - return OK; -} - -long int BlobCache::blob_random() { -#ifdef _WIN32 - return rand(); -#else - return nrand48(mRandState); -#endif -} - -void BlobCache::clean() { - // Remove a random cache entry until the total cache size gets below half - // the maximum total cache size. - while (mTotalSize > mMaxTotalSize / 2) { - size_t i = size_t(blob_random() % (mCacheEntries.size())); - const CacheEntry& entry(mCacheEntries[i]); - mTotalSize -= entry.getKey()->getSize() + entry.getValue()->getSize(); - mCacheEntries.removeAt(i); - } -} - -bool BlobCache::isCleanable() const { - return mTotalSize > mMaxTotalSize / 2; -} - -BlobCache::Blob::Blob(const void* data, size_t size, bool copyData): - mData(copyData ? malloc(size) : data), - mSize(size), - mOwnsData(copyData) { - if (data != NULL && copyData) { - memcpy(const_cast<void*>(mData), data, size); - } -} - -BlobCache::Blob::~Blob() { - if (mOwnsData) { - free(const_cast<void*>(mData)); - } -} - -bool BlobCache::Blob::operator<(const Blob& rhs) const { - if (mSize == rhs.mSize) { - return memcmp(mData, rhs.mData, mSize) < 0; - } else { - return mSize < rhs.mSize; - } -} - -const void* BlobCache::Blob::getData() const { - return mData; -} - -size_t BlobCache::Blob::getSize() const { - return mSize; -} - -BlobCache::CacheEntry::CacheEntry() { -} - -BlobCache::CacheEntry::CacheEntry(const sp<Blob>& key, const sp<Blob>& value): - mKey(key), - mValue(value) { -} - -BlobCache::CacheEntry::CacheEntry(const CacheEntry& ce): - mKey(ce.mKey), - mValue(ce.mValue) { -} - -bool BlobCache::CacheEntry::operator<(const CacheEntry& rhs) const { - return *mKey < *rhs.mKey; -} - -const BlobCache::CacheEntry& BlobCache::CacheEntry::operator=(const CacheEntry& rhs) { - mKey = rhs.mKey; - mValue = rhs.mValue; - return *this; -} - -sp<BlobCache::Blob> BlobCache::CacheEntry::getKey() const { - return mKey; -} - -sp<BlobCache::Blob> BlobCache::CacheEntry::getValue() const { - return mValue; -} - -void BlobCache::CacheEntry::setValue(const sp<Blob>& value) { - mValue = value; -} - -} // namespace android diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp deleted file mode 100644 index e60f5d8..0000000 --- a/libs/utils/CallStack.cpp +++ /dev/null @@ -1,138 +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. - */ - -#define LOG_TAG "CallStack" - -#include <string.h> - -#include <utils/Log.h> -#include <utils/Errors.h> -#include <utils/CallStack.h> -#include <corkscrew/backtrace.h> - -/*****************************************************************************/ -namespace android { - -CallStack::CallStack() : - mCount(0) { -} - -CallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) { - this->update(ignoreDepth+1, maxDepth); - this->dump(logtag); -} - -CallStack::CallStack(const CallStack& rhs) : - mCount(rhs.mCount) { - if (mCount) { - memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)); - } -} - -CallStack::~CallStack() { -} - -CallStack& CallStack::operator = (const CallStack& rhs) { - mCount = rhs.mCount; - if (mCount) { - memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)); - } - return *this; -} - -bool CallStack::operator == (const CallStack& rhs) const { - if (mCount != rhs.mCount) - return false; - return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0; -} - -bool CallStack::operator != (const CallStack& rhs) const { - return !operator == (rhs); -} - -bool CallStack::operator < (const CallStack& rhs) const { - if (mCount != rhs.mCount) - return mCount < rhs.mCount; - return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0; -} - -bool CallStack::operator >= (const CallStack& rhs) const { - return !operator < (rhs); -} - -bool CallStack::operator > (const CallStack& rhs) const { - if (mCount != rhs.mCount) - return mCount > rhs.mCount; - return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0; -} - -bool CallStack::operator <= (const CallStack& rhs) const { - return !operator > (rhs); -} - -const void* CallStack::operator [] (int index) const { - if (index >= int(mCount)) - return 0; - return reinterpret_cast<const void*>(mStack[index].absolute_pc); -} - -void CallStack::clear() { - mCount = 0; -} - -void CallStack::update(int32_t ignoreDepth, int32_t maxDepth) { - if (maxDepth > MAX_DEPTH) { - maxDepth = MAX_DEPTH; - } - ssize_t count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth); - mCount = count > 0 ? count : 0; -} - -void CallStack::dump(const char* logtag, const char* prefix) const { - backtrace_symbol_t symbols[mCount]; - - get_backtrace_symbols(mStack, mCount, symbols); - for (size_t i = 0; i < mCount; i++) { - char line[MAX_BACKTRACE_LINE_LENGTH]; - format_backtrace_line(i, &mStack[i], &symbols[i], - line, MAX_BACKTRACE_LINE_LENGTH); - ALOG(LOG_DEBUG, logtag, "%s%s", - prefix ? prefix : "", - line); - } - free_backtrace_symbols(symbols, mCount); -} - -String8 CallStack::toString(const char* prefix) const { - String8 str; - backtrace_symbol_t symbols[mCount]; - - get_backtrace_symbols(mStack, mCount, symbols); - for (size_t i = 0; i < mCount; i++) { - char line[MAX_BACKTRACE_LINE_LENGTH]; - format_backtrace_line(i, &mStack[i], &symbols[i], - line, MAX_BACKTRACE_LINE_LENGTH); - if (prefix) { - str.append(prefix); - } - str.append(line); - str.append("\n"); - } - free_backtrace_symbols(symbols, mCount); - return str; -} - -}; // namespace android diff --git a/libs/utils/CleanSpec.mk b/libs/utils/CleanSpec.mk deleted file mode 100644 index c3c5651..0000000 --- a/libs/utils/CleanSpec.mk +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (C) 2012 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 you don't need to do a full clean build but would like to touch -# a file or delete some intermediate files, add a clean step to the end -# of the list. These steps will only be run once, if they haven't been -# run before. -# -# E.g.: -# $(call add-clean-step, touch -c external/sqlite/sqlite3.h) -# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) -# -# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with -# files that are missing or have been moved. -# -# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. -# Use $(OUT_DIR) to refer to the "out" directory. -# -# If you need to re-do something that's already mentioned, just copy -# the command and add it to the bottom of the list. E.g., if a change -# that you made last week required touching a file and a change you -# made today requires touching the same file, just copy the old -# touch step and add it to the end of the list. -# -# ************************************************ -# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST -# ************************************************ - -# For example: -#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) -#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) -#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) -#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) - -# ************************************************ -# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST -# ************************************************ -$(call add-clean-step, rm -rf $(HOST_OUT)/obj/STATIC_LIBRARIES/libutils_intermediates/import_includes) -$(call add-clean-step, rm -rf $(HOST_OUT)/obj/STATIC_LIBRARIES/lib64utils_intermediates/import_includes) diff --git a/libs/utils/FileMap.cpp b/libs/utils/FileMap.cpp deleted file mode 100644 index 9ce370e..0000000 --- a/libs/utils/FileMap.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2006 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. - */ - -// -// Shared file mapping class. -// - -#define LOG_TAG "filemap" - -#include <utils/FileMap.h> -#include <utils/Log.h> - -#include <stdio.h> -#include <stdlib.h> - -#ifdef HAVE_POSIX_FILEMAP -#include <sys/mman.h> -#endif - -#include <string.h> -#include <memory.h> -#include <errno.h> -#include <assert.h> - -using namespace android; - -/*static*/ long FileMap::mPageSize = -1; - - -/* - * Constructor. Create an empty object. - */ -FileMap::FileMap(void) - : mRefCount(1), mFileName(NULL), mBasePtr(NULL), mBaseLength(0), - mDataPtr(NULL), mDataLength(0) -{ -} - -/* - * Destructor. - */ -FileMap::~FileMap(void) -{ - assert(mRefCount == 0); - - //printf("+++ removing FileMap %p %u\n", mDataPtr, mDataLength); - - mRefCount = -100; // help catch double-free - if (mFileName != NULL) { - free(mFileName); - } -#ifdef HAVE_POSIX_FILEMAP - if (mBasePtr && munmap(mBasePtr, mBaseLength) != 0) { - ALOGD("munmap(%p, %d) failed\n", mBasePtr, (int) mBaseLength); - } -#endif -#ifdef HAVE_WIN32_FILEMAP - if (mBasePtr && UnmapViewOfFile(mBasePtr) == 0) { - ALOGD("UnmapViewOfFile(%p) failed, error = %ld\n", mBasePtr, - GetLastError() ); - } - if (mFileMapping != INVALID_HANDLE_VALUE) { - CloseHandle(mFileMapping); - } - CloseHandle(mFileHandle); -#endif -} - - -/* - * Create a new mapping on an open file. - * - * Closing the file descriptor does not unmap the pages, so we don't - * claim ownership of the fd. - * - * Returns "false" on failure. - */ -bool FileMap::create(const char* origFileName, int fd, off64_t offset, size_t length, - bool readOnly) -{ -#ifdef HAVE_WIN32_FILEMAP - int adjust; - off64_t adjOffset; - size_t adjLength; - - if (mPageSize == -1) { - SYSTEM_INFO si; - - GetSystemInfo( &si ); - mPageSize = si.dwAllocationGranularity; - } - - DWORD protect = readOnly ? PAGE_READONLY : PAGE_READWRITE; - - mFileHandle = (HANDLE) _get_osfhandle(fd); - mFileMapping = CreateFileMapping( mFileHandle, NULL, protect, 0, 0, NULL); - if (mFileMapping == NULL) { - ALOGE("CreateFileMapping(%p, %lx) failed with error %ld\n", - mFileHandle, protect, GetLastError() ); - return false; - } - - adjust = offset % mPageSize; - adjOffset = offset - adjust; - adjLength = length + adjust; - - mBasePtr = MapViewOfFile( mFileMapping, - readOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, - 0, - (DWORD)(adjOffset), - adjLength ); - if (mBasePtr == NULL) { - ALOGE("MapViewOfFile(%ld, %ld) failed with error %ld\n", - adjOffset, adjLength, GetLastError() ); - CloseHandle(mFileMapping); - mFileMapping = INVALID_HANDLE_VALUE; - return false; - } -#endif -#ifdef HAVE_POSIX_FILEMAP - int prot, flags, adjust; - off64_t adjOffset; - size_t adjLength; - - void* ptr; - - assert(mRefCount == 1); - assert(fd >= 0); - assert(offset >= 0); - assert(length > 0); - - /* init on first use */ - if (mPageSize == -1) { -#if NOT_USING_KLIBC - mPageSize = sysconf(_SC_PAGESIZE); - if (mPageSize == -1) { - ALOGE("could not get _SC_PAGESIZE\n"); - return false; - } -#else - /* this holds for Linux, Darwin, Cygwin, and doesn't pain the ARM */ - mPageSize = 4096; -#endif - } - - adjust = offset % mPageSize; -try_again: - adjOffset = offset - adjust; - adjLength = length + adjust; - - flags = MAP_SHARED; - prot = PROT_READ; - if (!readOnly) - prot |= PROT_WRITE; - - ptr = mmap(NULL, adjLength, prot, flags, fd, adjOffset); - if (ptr == MAP_FAILED) { - // Cygwin does not seem to like file mapping files from an offset. - // So if we fail, try again with offset zero - if (adjOffset > 0) { - adjust = offset; - goto try_again; - } - - ALOGE("mmap(%ld,%ld) failed: %s\n", - (long) adjOffset, (long) adjLength, strerror(errno)); - return false; - } - mBasePtr = ptr; -#endif /* HAVE_POSIX_FILEMAP */ - - mFileName = origFileName != NULL ? strdup(origFileName) : NULL; - mBaseLength = adjLength; - mDataOffset = offset; - mDataPtr = (char*) mBasePtr + adjust; - mDataLength = length; - - assert(mBasePtr != NULL); - - ALOGV("MAP: base %p/%d data %p/%d\n", - mBasePtr, (int) mBaseLength, mDataPtr, (int) mDataLength); - - return true; -} - -/* - * Provide guidance to the system. - */ -int FileMap::advise(MapAdvice advice) -{ -#if HAVE_MADVISE - int cc, sysAdvice; - - switch (advice) { - case NORMAL: sysAdvice = MADV_NORMAL; break; - case RANDOM: sysAdvice = MADV_RANDOM; break; - case SEQUENTIAL: sysAdvice = MADV_SEQUENTIAL; break; - case WILLNEED: sysAdvice = MADV_WILLNEED; break; - case DONTNEED: sysAdvice = MADV_DONTNEED; break; - default: - assert(false); - return -1; - } - - cc = madvise(mBasePtr, mBaseLength, sysAdvice); - if (cc != 0) - ALOGW("madvise(%d) failed: %s\n", sysAdvice, strerror(errno)); - return cc; -#else - return -1; -#endif // HAVE_MADVISE -} diff --git a/libs/utils/JenkinsHash.cpp b/libs/utils/JenkinsHash.cpp deleted file mode 100644 index 52c9bb7..0000000 --- a/libs/utils/JenkinsHash.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -/* Implementation of Jenkins one-at-a-time hash function. These choices are - * optimized for code size and portability, rather than raw speed. But speed - * should still be quite good. - **/ - -#include <utils/JenkinsHash.h> - -namespace android { - -hash_t JenkinsHashWhiten(uint32_t hash) { - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - return hash; -} - -uint32_t JenkinsHashMixBytes(uint32_t hash, const uint8_t* bytes, size_t size) { - hash = JenkinsHashMix(hash, (uint32_t)size); - size_t i; - for (i = 0; i < (size & -4); i += 4) { - uint32_t data = bytes[i] | (bytes[i+1] << 8) | (bytes[i+2] << 16) | (bytes[i+3] << 24); - hash = JenkinsHashMix(hash, data); - } - if (size & 3) { - uint32_t data = bytes[i]; - data |= ((size & 3) > 1) ? (bytes[i+1] << 8) : 0; - data |= ((size & 3) > 2) ? (bytes[i+2] << 16) : 0; - hash = JenkinsHashMix(hash, data); - } - return hash; -} - -uint32_t JenkinsHashMixShorts(uint32_t hash, const uint16_t* shorts, size_t size) { - hash = JenkinsHashMix(hash, (uint32_t)size); - size_t i; - for (i = 0; i < (size & -2); i += 2) { - uint32_t data = shorts[i] | (shorts[i+1] << 16); - hash = JenkinsHashMix(hash, data); - } - if (size & 1) { - uint32_t data = shorts[i]; - hash = JenkinsHashMix(hash, data); - } - return hash; -} - -} - diff --git a/libs/utils/LinearAllocator.cpp b/libs/utils/LinearAllocator.cpp deleted file mode 100644 index a07a291..0000000 --- a/libs/utils/LinearAllocator.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright 2012, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define LOG_TAG "LinearAllocator" -#define LOG_NDEBUG 1 - -#include <stdlib.h> -#include <utils/LinearAllocator.h> -#include <utils/Log.h> - - -// The ideal size of a page allocation (these need to be multiples of 8) -#define INITIAL_PAGE_SIZE ((size_t)4096) // 4kb -#define MAX_PAGE_SIZE ((size_t)131072) // 128kb - -// The maximum amount of wasted space we can have per page -// Allocations exceeding this will have their own dedicated page -// If this is too low, we will malloc too much -// Too high, and we may waste too much space -// Must be smaller than INITIAL_PAGE_SIZE -#define MAX_WASTE_SIZE ((size_t)1024) - -#if ALIGN_DOUBLE -#define ALIGN_SZ (sizeof(double)) -#else -#define ALIGN_SZ (sizeof(int)) -#endif - -#define ALIGN(x) ((x + ALIGN_SZ - 1 ) & ~(ALIGN_SZ - 1)) -#define ALIGN_PTR(p) ((void*)(ALIGN((size_t)p))) - -#if LOG_NDEBUG -#define ADD_ALLOCATION(size) -#define RM_ALLOCATION(size) -#else -#include <utils/Thread.h> -#include <utils/Timers.h> -static size_t s_totalAllocations = 0; -static nsecs_t s_nextLog = 0; -static android::Mutex s_mutex; - -static void _logUsageLocked() { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - if (now > s_nextLog) { - s_nextLog = now + milliseconds_to_nanoseconds(10); - ALOGV("Total memory usage: %zu kb", s_totalAllocations / 1024); - } -} - -static void _addAllocation(size_t size) { - android::AutoMutex lock(s_mutex); - s_totalAllocations += size; - _logUsageLocked(); -} - -#define ADD_ALLOCATION(size) _addAllocation(size); -#define RM_ALLOCATION(size) _addAllocation(-size); -#endif - -#define min(x,y) (((x) < (y)) ? (x) : (y)) - -namespace android { - -class LinearAllocator::Page { -public: - Page* next() { return mNextPage; } - void setNext(Page* next) { mNextPage = next; } - - Page() - : mNextPage(0) - {} - - void* operator new(size_t size, void* buf) { return buf; } - - void* start() { - return (void*) (((size_t)this) + sizeof(Page)); - } - - void* end(int pageSize) { - return (void*) (((size_t)start()) + pageSize); - } - -private: - Page(const Page& other) {} - Page* mNextPage; -}; - -LinearAllocator::LinearAllocator() - : mPageSize(INITIAL_PAGE_SIZE) - , mMaxAllocSize(MAX_WASTE_SIZE) - , mNext(0) - , mCurrentPage(0) - , mPages(0) - , mTotalAllocated(0) - , mWastedSpace(0) - , mPageCount(0) - , mDedicatedPageCount(0) {} - -LinearAllocator::~LinearAllocator(void) { - Page* p = mPages; - while (p) { - Page* next = p->next(); - p->~Page(); - free(p); - RM_ALLOCATION(mPageSize); - p = next; - } -} - -void* LinearAllocator::start(Page* p) { - return ALIGN_PTR(((size_t*)p) + sizeof(Page)); -} - -void* LinearAllocator::end(Page* p) { - return ((char*)p) + mPageSize; -} - -bool LinearAllocator::fitsInCurrentPage(size_t size) { - return mNext && ((char*)mNext + size) <= end(mCurrentPage); -} - -void LinearAllocator::ensureNext(size_t size) { - if (fitsInCurrentPage(size)) return; - - if (mCurrentPage && mPageSize < MAX_PAGE_SIZE) { - mPageSize = min(MAX_PAGE_SIZE, mPageSize * 2); - mPageSize = ALIGN(mPageSize); - } - mWastedSpace += mPageSize; - Page* p = newPage(mPageSize); - if (mCurrentPage) { - mCurrentPage->setNext(p); - } - mCurrentPage = p; - if (!mPages) { - mPages = mCurrentPage; - } - mNext = start(mCurrentPage); -} - -void* LinearAllocator::alloc(size_t size) { - size = ALIGN(size); - if (size > mMaxAllocSize && !fitsInCurrentPage(size)) { - ALOGV("Exceeded max size %zu > %zu", size, mMaxAllocSize); - // Allocation is too large, create a dedicated page for the allocation - Page* page = newPage(size); - mDedicatedPageCount++; - page->setNext(mPages); - mPages = page; - if (!mCurrentPage) - mCurrentPage = mPages; - return start(page); - } - ensureNext(size); - void* ptr = mNext; - mNext = ((char*)mNext) + size; - mWastedSpace -= size; - return ptr; -} - -void LinearAllocator::rewindIfLastAlloc(void* ptr, size_t allocSize) { - // Don't bother rewinding across pages - allocSize = ALIGN(allocSize); - if (ptr >= start(mCurrentPage) && ptr < end(mCurrentPage) - && ptr == ((char*)mNext - allocSize)) { - mTotalAllocated -= allocSize; - mWastedSpace += allocSize; - mNext = ptr; - } -} - -LinearAllocator::Page* LinearAllocator::newPage(size_t pageSize) { - pageSize = ALIGN(pageSize + sizeof(LinearAllocator::Page)); - ADD_ALLOCATION(pageSize); - mTotalAllocated += pageSize; - mPageCount++; - void* buf = malloc(pageSize); - return new (buf) Page(); -} - -static const char* toSize(size_t value, float& result) { - if (value < 2000) { - result = value; - return "B"; - } - if (value < 2000000) { - result = value / 1024.0f; - return "KB"; - } - result = value / 1048576.0f; - return "MB"; -} - -void LinearAllocator::dumpMemoryStats(const char* prefix) { - float prettySize; - const char* prettySuffix; - prettySuffix = toSize(mTotalAllocated, prettySize); - ALOGD("%sTotal allocated: %.2f%s", prefix, prettySize, prettySuffix); - prettySuffix = toSize(mWastedSpace, prettySize); - ALOGD("%sWasted space: %.2f%s (%.1f%%)", prefix, prettySize, prettySuffix, - (float) mWastedSpace / (float) mTotalAllocated * 100.0f); - ALOGD("%sPages %zu (dedicated %zu)", prefix, mPageCount, mDedicatedPageCount); -} - -}; // namespace android diff --git a/libs/utils/LinearTransform.cpp b/libs/utils/LinearTransform.cpp deleted file mode 100644 index b7d28d4..0000000 --- a/libs/utils/LinearTransform.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2011 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 __STDC_LIMIT_MACROS - -#include <assert.h> -#include <stdint.h> - -#include <utils/LinearTransform.h> - -namespace android { - -template<class T> static inline T ABS(T x) { return (x < 0) ? -x : x; } - -// Static math methods involving linear transformations -static bool scale_u64_to_u64( - uint64_t val, - uint32_t N, - uint32_t D, - uint64_t* res, - bool round_up_not_down) { - uint64_t tmp1, tmp2; - uint32_t r; - - assert(res); - assert(D); - - // Let U32(X) denote a uint32_t containing the upper 32 bits of a 64 bit - // integer X. - // Let L32(X) denote a uint32_t containing the lower 32 bits of a 64 bit - // integer X. - // Let X[A, B] with A <= B denote bits A through B of the integer X. - // Let (A | B) denote the concatination of two 32 bit ints, A and B. - // IOW X = (A | B) => U32(X) == A && L32(X) == B - // - // compute M = val * N (a 96 bit int) - // --------------------------------- - // tmp2 = U32(val) * N (a 64 bit int) - // tmp1 = L32(val) * N (a 64 bit int) - // which means - // M = val * N = (tmp2 << 32) + tmp1 - tmp2 = (val >> 32) * N; - tmp1 = (val & UINT32_MAX) * N; - - // compute M[32, 95] - // tmp2 = tmp2 + U32(tmp1) - // = (U32(val) * N) + U32(L32(val) * N) - // = M[32, 95] - tmp2 += tmp1 >> 32; - - // if M[64, 95] >= D, then M/D has bits > 63 set and we have - // an overflow. - if ((tmp2 >> 32) >= D) { - *res = UINT64_MAX; - return false; - } - - // Divide. Going in we know - // tmp2 = M[32, 95] - // U32(tmp2) < D - r = tmp2 % D; - tmp2 /= D; - - // At this point - // tmp1 = L32(val) * N - // tmp2 = M[32, 95] / D - // = (M / D)[32, 95] - // r = M[32, 95] % D - // U32(tmp2) = 0 - // - // compute tmp1 = (r | M[0, 31]) - tmp1 = (tmp1 & UINT32_MAX) | ((uint64_t)r << 32); - - // Divide again. Keep the remainder around in order to round properly. - r = tmp1 % D; - tmp1 /= D; - - // At this point - // tmp2 = (M / D)[32, 95] - // tmp1 = (M / D)[ 0, 31] - // r = M % D - // U32(tmp1) = 0 - // U32(tmp2) = 0 - - // Pack the result and deal with the round-up case (As well as the - // remote possiblility over overflow in such a case). - *res = (tmp2 << 32) | tmp1; - if (r && round_up_not_down) { - ++(*res); - if (!(*res)) { - *res = UINT64_MAX; - return false; - } - } - - return true; -} - -static bool linear_transform_s64_to_s64( - int64_t val, - int64_t basis1, - int32_t N, - uint32_t D, - bool invert_frac, - int64_t basis2, - int64_t* out) { - uint64_t scaled, res; - uint64_t abs_val; - bool is_neg; - - if (!out) - return false; - - // Compute abs(val - basis_64). Keep track of whether or not this delta - // will be negative after the scale opertaion. - if (val < basis1) { - is_neg = true; - abs_val = basis1 - val; - } else { - is_neg = false; - abs_val = val - basis1; - } - - if (N < 0) - is_neg = !is_neg; - - if (!scale_u64_to_u64(abs_val, - invert_frac ? D : ABS(N), - invert_frac ? ABS(N) : D, - &scaled, - is_neg)) - return false; // overflow/undeflow - - // if scaled is >= 0x8000<etc>, then we are going to overflow or - // underflow unless ABS(basis2) is large enough to pull us back into the - // non-overflow/underflow region. - if (scaled & INT64_MIN) { - if (is_neg && (basis2 < 0)) - return false; // certain underflow - - if (!is_neg && (basis2 >= 0)) - return false; // certain overflow - - if (ABS(basis2) <= static_cast<int64_t>(scaled & INT64_MAX)) - return false; // not enough - - // Looks like we are OK - *out = (is_neg ? (-scaled) : scaled) + basis2; - } else { - // Scaled fits within signed bounds, so we just need to check for - // over/underflow for two signed integers. Basically, if both scaled - // and basis2 have the same sign bit, and the result has a different - // sign bit, then we have under/overflow. An easy way to compute this - // is - // (scaled_signbit XNOR basis_signbit) && - // (scaled_signbit XOR res_signbit) - // == - // (scaled_signbit XOR basis_signbit XOR 1) && - // (scaled_signbit XOR res_signbit) - - if (is_neg) - scaled = -scaled; - res = scaled + basis2; - - if ((scaled ^ basis2 ^ INT64_MIN) & (scaled ^ res) & INT64_MIN) - return false; - - *out = res; - } - - return true; -} - -bool LinearTransform::doForwardTransform(int64_t a_in, int64_t* b_out) const { - if (0 == a_to_b_denom) - return false; - - return linear_transform_s64_to_s64(a_in, - a_zero, - a_to_b_numer, - a_to_b_denom, - false, - b_zero, - b_out); -} - -bool LinearTransform::doReverseTransform(int64_t b_in, int64_t* a_out) const { - if (0 == a_to_b_numer) - return false; - - return linear_transform_s64_to_s64(b_in, - b_zero, - a_to_b_numer, - a_to_b_denom, - true, - a_zero, - a_out); -} - -template <class T> void LinearTransform::reduce(T* N, T* D) { - T a, b; - if (!N || !D || !(*D)) { - assert(false); - return; - } - - a = *N; - b = *D; - - if (a == 0) { - *D = 1; - return; - } - - // This implements Euclid's method to find GCD. - if (a < b) { - T tmp = a; - a = b; - b = tmp; - } - - while (1) { - // a is now the greater of the two. - const T remainder = a % b; - if (remainder == 0) { - *N /= b; - *D /= b; - return; - } - // by swapping remainder and b, we are guaranteeing that a is - // still the greater of the two upon entrance to the loop. - a = b; - b = remainder; - } -}; - -template void LinearTransform::reduce<uint64_t>(uint64_t* N, uint64_t* D); -template void LinearTransform::reduce<uint32_t>(uint32_t* N, uint32_t* D); - -void LinearTransform::reduce(int32_t* N, uint32_t* D) { - if (N && D && *D) { - if (*N < 0) { - *N = -(*N); - reduce(reinterpret_cast<uint32_t*>(N), D); - *N = -(*N); - } else { - reduce(reinterpret_cast<uint32_t*>(N), D); - } - } -} - -} // namespace android diff --git a/libs/utils/Log.cpp b/libs/utils/Log.cpp deleted file mode 100644 index bffb56e..0000000 --- a/libs/utils/Log.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2012 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 "Log" - -#include <utils/Log.h> -#include <utils/Timers.h> - -namespace android { - -LogIfSlow::LogIfSlow(const char* tag, android_LogPriority priority, - int timeoutMillis, const char* message) : - mTag(tag), mPriority(priority), mTimeoutMillis(timeoutMillis), mMessage(message), - mStart(systemTime(SYSTEM_TIME_BOOTTIME)) { -} - -LogIfSlow::~LogIfSlow() { - int durationMillis = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_BOOTTIME) - mStart); - if (durationMillis > mTimeoutMillis) { - LOG_PRI(mPriority, mTag, "%s: %dms", mMessage, durationMillis); - } -} - -} // namespace android diff --git a/libs/utils/Looper.cpp b/libs/utils/Looper.cpp deleted file mode 100644 index c51df2d..0000000 --- a/libs/utils/Looper.cpp +++ /dev/null @@ -1,573 +0,0 @@ -// -// Copyright 2010 The Android Open Source Project -// -// A looper implementation based on epoll(). -// -#define LOG_TAG "Looper" - -//#define LOG_NDEBUG 0 - -// Debugs poll and wake interactions. -#define DEBUG_POLL_AND_WAKE 0 - -// Debugs callback registration and invocation. -#define DEBUG_CALLBACKS 0 - -#include <cutils/log.h> -#include <utils/Looper.h> -#include <utils/Timers.h> - -#include <unistd.h> -#include <fcntl.h> -#include <limits.h> - - -namespace android { - -// --- WeakMessageHandler --- - -WeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) : - mHandler(handler) { -} - -WeakMessageHandler::~WeakMessageHandler() { -} - -void WeakMessageHandler::handleMessage(const Message& message) { - sp<MessageHandler> handler = mHandler.promote(); - if (handler != NULL) { - handler->handleMessage(message); - } -} - - -// --- SimpleLooperCallback --- - -SimpleLooperCallback::SimpleLooperCallback(ALooper_callbackFunc callback) : - mCallback(callback) { -} - -SimpleLooperCallback::~SimpleLooperCallback() { -} - -int SimpleLooperCallback::handleEvent(int fd, int events, void* data) { - return mCallback(fd, events, data); -} - - -// --- Looper --- - -// Hint for number of file descriptors to be associated with the epoll instance. -static const int EPOLL_SIZE_HINT = 8; - -// Maximum number of file descriptors for which to retrieve poll events each iteration. -static const int EPOLL_MAX_EVENTS = 16; - -static pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT; -static pthread_key_t gTLSKey = 0; - -Looper::Looper(bool allowNonCallbacks) : - mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), - mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { - int wakeFds[2]; - int result = pipe(wakeFds); - LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); - - mWakeReadPipeFd = wakeFds[0]; - mWakeWritePipeFd = wakeFds[1]; - - result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); - LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d", - errno); - - result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); - LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d", - errno); - - mIdling = false; - - // Allocate the epoll instance and register the wake pipe. - mEpollFd = epoll_create(EPOLL_SIZE_HINT); - LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); - - struct epoll_event eventItem; - memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union - eventItem.events = EPOLLIN; - eventItem.data.fd = mWakeReadPipeFd; - result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem); - LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", - errno); -} - -Looper::~Looper() { - close(mWakeReadPipeFd); - close(mWakeWritePipeFd); - close(mEpollFd); -} - -void Looper::initTLSKey() { - int result = pthread_key_create(& gTLSKey, threadDestructor); - LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key."); -} - -void Looper::threadDestructor(void *st) { - Looper* const self = static_cast<Looper*>(st); - if (self != NULL) { - self->decStrong((void*)threadDestructor); - } -} - -void Looper::setForThread(const sp<Looper>& looper) { - sp<Looper> old = getForThread(); // also has side-effect of initializing TLS - - if (looper != NULL) { - looper->incStrong((void*)threadDestructor); - } - - pthread_setspecific(gTLSKey, looper.get()); - - if (old != NULL) { - old->decStrong((void*)threadDestructor); - } -} - -sp<Looper> Looper::getForThread() { - int result = pthread_once(& gTLSOnce, initTLSKey); - LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed"); - - return (Looper*)pthread_getspecific(gTLSKey); -} - -sp<Looper> Looper::prepare(int opts) { - bool allowNonCallbacks = opts & ALOOPER_PREPARE_ALLOW_NON_CALLBACKS; - sp<Looper> looper = Looper::getForThread(); - if (looper == NULL) { - looper = new Looper(allowNonCallbacks); - Looper::setForThread(looper); - } - if (looper->getAllowNonCallbacks() != allowNonCallbacks) { - ALOGW("Looper already prepared for this thread with a different value for the " - "ALOOPER_PREPARE_ALLOW_NON_CALLBACKS option."); - } - return looper; -} - -bool Looper::getAllowNonCallbacks() const { - return mAllowNonCallbacks; -} - -int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { - int result = 0; - for (;;) { - while (mResponseIndex < mResponses.size()) { - const Response& response = mResponses.itemAt(mResponseIndex++); - int ident = response.request.ident; - if (ident >= 0) { - int fd = response.request.fd; - int events = response.events; - void* data = response.request.data; -#if DEBUG_POLL_AND_WAKE - ALOGD("%p ~ pollOnce - returning signalled identifier %d: " - "fd=%d, events=0x%x, data=%p", - this, ident, fd, events, data); -#endif - if (outFd != NULL) *outFd = fd; - if (outEvents != NULL) *outEvents = events; - if (outData != NULL) *outData = data; - return ident; - } - } - - if (result != 0) { -#if DEBUG_POLL_AND_WAKE - ALOGD("%p ~ pollOnce - returning result %d", this, result); -#endif - if (outFd != NULL) *outFd = 0; - if (outEvents != NULL) *outEvents = 0; - if (outData != NULL) *outData = NULL; - return result; - } - - result = pollInner(timeoutMillis); - } -} - -int Looper::pollInner(int timeoutMillis) { -#if DEBUG_POLL_AND_WAKE - ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis); -#endif - - // Adjust the timeout based on when the next message is due. - if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime); - if (messageTimeoutMillis >= 0 - && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) { - timeoutMillis = messageTimeoutMillis; - } -#if DEBUG_POLL_AND_WAKE - ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d", - this, mNextMessageUptime - now, timeoutMillis); -#endif - } - - // Poll. - int result = ALOOPER_POLL_WAKE; - mResponses.clear(); - mResponseIndex = 0; - - // We are about to idle. - mIdling = true; - - struct epoll_event eventItems[EPOLL_MAX_EVENTS]; - int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); - - // No longer idling. - mIdling = false; - - // Acquire lock. - mLock.lock(); - - // Check for poll error. - if (eventCount < 0) { - if (errno == EINTR) { - goto Done; - } - ALOGW("Poll failed with an unexpected error, errno=%d", errno); - result = ALOOPER_POLL_ERROR; - goto Done; - } - - // Check for poll timeout. - if (eventCount == 0) { -#if DEBUG_POLL_AND_WAKE - ALOGD("%p ~ pollOnce - timeout", this); -#endif - result = ALOOPER_POLL_TIMEOUT; - goto Done; - } - - // Handle all events. -#if DEBUG_POLL_AND_WAKE - ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount); -#endif - - for (int i = 0; i < eventCount; i++) { - int fd = eventItems[i].data.fd; - uint32_t epollEvents = eventItems[i].events; - if (fd == mWakeReadPipeFd) { - if (epollEvents & EPOLLIN) { - awoken(); - } else { - ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents); - } - } else { - ssize_t requestIndex = mRequests.indexOfKey(fd); - if (requestIndex >= 0) { - int events = 0; - if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT; - if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT; - if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR; - if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP; - pushResponse(events, mRequests.valueAt(requestIndex)); - } else { - ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is " - "no longer registered.", epollEvents, fd); - } - } - } -Done: ; - - // Invoke pending message callbacks. - mNextMessageUptime = LLONG_MAX; - while (mMessageEnvelopes.size() != 0) { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0); - if (messageEnvelope.uptime <= now) { - // Remove the envelope from the list. - // We keep a strong reference to the handler until the call to handleMessage - // finishes. Then we drop it so that the handler can be deleted *before* - // we reacquire our lock. - { // obtain handler - sp<MessageHandler> handler = messageEnvelope.handler; - Message message = messageEnvelope.message; - mMessageEnvelopes.removeAt(0); - mSendingMessage = true; - mLock.unlock(); - -#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS - ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d", - this, handler.get(), message.what); -#endif - handler->handleMessage(message); - } // release handler - - mLock.lock(); - mSendingMessage = false; - result = ALOOPER_POLL_CALLBACK; - } else { - // The last message left at the head of the queue determines the next wakeup time. - mNextMessageUptime = messageEnvelope.uptime; - break; - } - } - - // Release lock. - mLock.unlock(); - - // Invoke all response callbacks. - for (size_t i = 0; i < mResponses.size(); i++) { - Response& response = mResponses.editItemAt(i); - if (response.request.ident == ALOOPER_POLL_CALLBACK) { - int fd = response.request.fd; - int events = response.events; - void* data = response.request.data; -#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS - ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", - this, response.request.callback.get(), fd, events, data); -#endif - int callbackResult = response.request.callback->handleEvent(fd, events, data); - if (callbackResult == 0) { - removeFd(fd); - } - // Clear the callback reference in the response structure promptly because we - // will not clear the response vector itself until the next poll. - response.request.callback.clear(); - result = ALOOPER_POLL_CALLBACK; - } - } - return result; -} - -int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { - if (timeoutMillis <= 0) { - int result; - do { - result = pollOnce(timeoutMillis, outFd, outEvents, outData); - } while (result == ALOOPER_POLL_CALLBACK); - return result; - } else { - nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC) - + milliseconds_to_nanoseconds(timeoutMillis); - - for (;;) { - int result = pollOnce(timeoutMillis, outFd, outEvents, outData); - if (result != ALOOPER_POLL_CALLBACK) { - return result; - } - - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - timeoutMillis = toMillisecondTimeoutDelay(now, endTime); - if (timeoutMillis == 0) { - return ALOOPER_POLL_TIMEOUT; - } - } - } -} - -void Looper::wake() { -#if DEBUG_POLL_AND_WAKE - ALOGD("%p ~ wake", this); -#endif - - ssize_t nWrite; - do { - nWrite = write(mWakeWritePipeFd, "W", 1); - } while (nWrite == -1 && errno == EINTR); - - if (nWrite != 1) { - if (errno != EAGAIN) { - ALOGW("Could not write wake signal, errno=%d", errno); - } - } -} - -void Looper::awoken() { -#if DEBUG_POLL_AND_WAKE - ALOGD("%p ~ awoken", this); -#endif - - char buffer[16]; - ssize_t nRead; - do { - nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); - } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); -} - -void Looper::pushResponse(int events, const Request& request) { - Response response; - response.events = events; - response.request = request; - mResponses.push(response); -} - -int Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) { - return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data); -} - -int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) { -#if DEBUG_CALLBACKS - ALOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident, - events, callback.get(), data); -#endif - - if (!callback.get()) { - if (! mAllowNonCallbacks) { - ALOGE("Invalid attempt to set NULL callback but not allowed for this looper."); - return -1; - } - - if (ident < 0) { - ALOGE("Invalid attempt to set NULL callback with ident < 0."); - return -1; - } - } else { - ident = ALOOPER_POLL_CALLBACK; - } - - int epollEvents = 0; - if (events & ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN; - if (events & ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT; - - { // acquire lock - AutoMutex _l(mLock); - - Request request; - request.fd = fd; - request.ident = ident; - request.callback = callback; - request.data = data; - - struct epoll_event eventItem; - memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union - eventItem.events = epollEvents; - eventItem.data.fd = fd; - - ssize_t requestIndex = mRequests.indexOfKey(fd); - if (requestIndex < 0) { - int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); - if (epollResult < 0) { - ALOGE("Error adding epoll events for fd %d, errno=%d", fd, errno); - return -1; - } - mRequests.add(fd, request); - } else { - int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem); - if (epollResult < 0) { - ALOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno); - return -1; - } - mRequests.replaceValueAt(requestIndex, request); - } - } // release lock - return 1; -} - -int Looper::removeFd(int fd) { -#if DEBUG_CALLBACKS - ALOGD("%p ~ removeFd - fd=%d", this, fd); -#endif - - { // acquire lock - AutoMutex _l(mLock); - ssize_t requestIndex = mRequests.indexOfKey(fd); - if (requestIndex < 0) { - return 0; - } - - int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL); - if (epollResult < 0) { - ALOGE("Error removing epoll events for fd %d, errno=%d", fd, errno); - return -1; - } - - mRequests.removeItemsAt(requestIndex); - } // release lock - return 1; -} - -void Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - sendMessageAtTime(now, handler, message); -} - -void Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler, - const Message& message) { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - sendMessageAtTime(now + uptimeDelay, handler, message); -} - -void Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler, - const Message& message) { -#if DEBUG_CALLBACKS - ALOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d", - this, uptime, handler.get(), message.what); -#endif - - size_t i = 0; - { // acquire lock - AutoMutex _l(mLock); - - size_t messageCount = mMessageEnvelopes.size(); - while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) { - i += 1; - } - - MessageEnvelope messageEnvelope(uptime, handler, message); - mMessageEnvelopes.insertAt(messageEnvelope, i, 1); - - // Optimization: If the Looper is currently sending a message, then we can skip - // the call to wake() because the next thing the Looper will do after processing - // messages is to decide when the next wakeup time should be. In fact, it does - // not even matter whether this code is running on the Looper thread. - if (mSendingMessage) { - return; - } - } // release lock - - // Wake the poll loop only when we enqueue a new message at the head. - if (i == 0) { - wake(); - } -} - -void Looper::removeMessages(const sp<MessageHandler>& handler) { -#if DEBUG_CALLBACKS - ALOGD("%p ~ removeMessages - handler=%p", this, handler.get()); -#endif - - { // acquire lock - AutoMutex _l(mLock); - - for (size_t i = mMessageEnvelopes.size(); i != 0; ) { - const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); - if (messageEnvelope.handler == handler) { - mMessageEnvelopes.removeAt(i); - } - } - } // release lock -} - -void Looper::removeMessages(const sp<MessageHandler>& handler, int what) { -#if DEBUG_CALLBACKS - ALOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what); -#endif - - { // acquire lock - AutoMutex _l(mLock); - - for (size_t i = mMessageEnvelopes.size(); i != 0; ) { - const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); - if (messageEnvelope.handler == handler - && messageEnvelope.message.what == what) { - mMessageEnvelopes.removeAt(i); - } - } - } // release lock -} - -bool Looper::isIdling() const { - return mIdling; -} - -} // namespace android diff --git a/libs/utils/MODULE_LICENSE_APACHE2 b/libs/utils/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29..0000000 --- a/libs/utils/MODULE_LICENSE_APACHE2 +++ /dev/null diff --git a/libs/utils/NOTICE b/libs/utils/NOTICE deleted file mode 100644 index c5b1efa..0000000 --- a/libs/utils/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, 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. - - 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. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/libs/utils/PropertyMap.cpp b/libs/utils/PropertyMap.cpp deleted file mode 100644 index 5520702..0000000 --- a/libs/utils/PropertyMap.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2008 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 "PropertyMap" - -#include <stdlib.h> -#include <string.h> - -#include <utils/PropertyMap.h> -#include <utils/Log.h> - -// Enables debug output for the parser. -#define DEBUG_PARSER 0 - -// Enables debug output for parser performance. -#define DEBUG_PARSER_PERFORMANCE 0 - - -namespace android { - -static const char* WHITESPACE = " \t\r"; -static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r="; - - -// --- PropertyMap --- - -PropertyMap::PropertyMap() { -} - -PropertyMap::~PropertyMap() { -} - -void PropertyMap::clear() { - mProperties.clear(); -} - -void PropertyMap::addProperty(const String8& key, const String8& value) { - mProperties.add(key, value); -} - -bool PropertyMap::hasProperty(const String8& key) const { - return mProperties.indexOfKey(key) >= 0; -} - -bool PropertyMap::tryGetProperty(const String8& key, String8& outValue) const { - ssize_t index = mProperties.indexOfKey(key); - if (index < 0) { - return false; - } - - outValue = mProperties.valueAt(index); - return true; -} - -bool PropertyMap::tryGetProperty(const String8& key, bool& outValue) const { - int32_t intValue; - if (!tryGetProperty(key, intValue)) { - return false; - } - - outValue = intValue; - return true; -} - -bool PropertyMap::tryGetProperty(const String8& key, int32_t& outValue) const { - String8 stringValue; - if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) { - return false; - } - - char* end; - int value = strtol(stringValue.string(), & end, 10); - if (*end != '\0') { - ALOGW("Property key '%s' has invalid value '%s'. Expected an integer.", - key.string(), stringValue.string()); - return false; - } - outValue = value; - return true; -} - -bool PropertyMap::tryGetProperty(const String8& key, float& outValue) const { - String8 stringValue; - if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) { - return false; - } - - char* end; - float value = strtof(stringValue.string(), & end); - if (*end != '\0') { - ALOGW("Property key '%s' has invalid value '%s'. Expected a float.", - key.string(), stringValue.string()); - return false; - } - outValue = value; - return true; -} - -void PropertyMap::addAll(const PropertyMap* map) { - for (size_t i = 0; i < map->mProperties.size(); i++) { - mProperties.add(map->mProperties.keyAt(i), map->mProperties.valueAt(i)); - } -} - -status_t PropertyMap::load(const String8& filename, PropertyMap** outMap) { - *outMap = NULL; - - Tokenizer* tokenizer; - status_t status = Tokenizer::open(filename, &tokenizer); - if (status) { - ALOGE("Error %d opening property file %s.", status, filename.string()); - } else { - PropertyMap* map = new PropertyMap(); - if (!map) { - ALOGE("Error allocating property map."); - status = NO_MEMORY; - } else { -#if DEBUG_PARSER_PERFORMANCE - nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC); -#endif - Parser parser(map, tokenizer); - status = parser.parse(); -#if DEBUG_PARSER_PERFORMANCE - nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime; - ALOGD("Parsed property file '%s' %d lines in %0.3fms.", - tokenizer->getFilename().string(), tokenizer->getLineNumber(), - elapsedTime / 1000000.0); -#endif - if (status) { - delete map; - } else { - *outMap = map; - } - } - delete tokenizer; - } - return status; -} - - -// --- PropertyMap::Parser --- - -PropertyMap::Parser::Parser(PropertyMap* map, Tokenizer* tokenizer) : - mMap(map), mTokenizer(tokenizer) { -} - -PropertyMap::Parser::~Parser() { -} - -status_t PropertyMap::Parser::parse() { - while (!mTokenizer->isEof()) { -#if DEBUG_PARSER - ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(), - mTokenizer->peekRemainderOfLine().string()); -#endif - - mTokenizer->skipDelimiters(WHITESPACE); - - if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') { - String8 keyToken = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER); - if (keyToken.isEmpty()) { - ALOGE("%s: Expected non-empty property key.", mTokenizer->getLocation().string()); - return BAD_VALUE; - } - - mTokenizer->skipDelimiters(WHITESPACE); - - if (mTokenizer->nextChar() != '=') { - ALOGE("%s: Expected '=' between property key and value.", - mTokenizer->getLocation().string()); - return BAD_VALUE; - } - - mTokenizer->skipDelimiters(WHITESPACE); - - String8 valueToken = mTokenizer->nextToken(WHITESPACE); - if (valueToken.find("\\", 0) >= 0 || valueToken.find("\"", 0) >= 0) { - ALOGE("%s: Found reserved character '\\' or '\"' in property value.", - mTokenizer->getLocation().string()); - return BAD_VALUE; - } - - mTokenizer->skipDelimiters(WHITESPACE); - if (!mTokenizer->isEol()) { - ALOGE("%s: Expected end of line, got '%s'.", - mTokenizer->getLocation().string(), - mTokenizer->peekRemainderOfLine().string()); - return BAD_VALUE; - } - - if (mMap->hasProperty(keyToken)) { - ALOGE("%s: Duplicate property value for key '%s'.", - mTokenizer->getLocation().string(), keyToken.string()); - return BAD_VALUE; - } - - mMap->addProperty(keyToken, valueToken); - } - - mTokenizer->nextLine(); - } - return NO_ERROR; -} - -} // namespace android diff --git a/libs/utils/README b/libs/utils/README deleted file mode 100644 index 01741e0..0000000 --- a/libs/utils/README +++ /dev/null @@ -1,289 +0,0 @@ -Android Utility Function Library -================================ - - -If you need a feature that is native to Linux but not present on other -platforms, construct a platform-dependent implementation that shares -the Linux interface. That way the actual device runs as "light" as -possible. - -If that isn't feasible, create a system-independent interface and hide -the details. - -The ultimate goal is *not* to create a super-duper platform abstraction -layer. The goal is to provide an optimized solution for Linux with -reasonable implementations for other platforms. - - - -Resource overlay -================ - - -Introduction ------------- - -Overlay packages are special .apk files which provide no code but -additional resource values (and possibly new configurations) for -resources in other packages. When an application requests resources, -the system will return values from either the application's original -package or any associated overlay package. Any redirection is completely -transparent to the calling application. - -Resource values have the following precedence table, listed in -descending precedence. - - * overlay package, matching config (eg res/values-en-land) - - * original package, matching config - - * overlay package, no config (eg res/values) - - * original package, no config - -During compilation, overlay packages are differentiated from regular -packages by passing the -o flag to aapt. - - -Background ----------- - -This section provides generic background material on resources in -Android. - - -How resources are bundled in .apk files -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Android .apk files are .zip files, usually housing .dex code, -certificates and resources, though packages containing resources but -no code are possible. Resources can be divided into the following -categories; a `configuration' indicates a set of phone language, display -density, network operator, etc. - - * assets: uncompressed, raw files packaged as part of an .apk and - explicitly referenced by filename. These files are - independent of configuration. - - * res/drawable: bitmap or xml graphics. Each file may have different - values depending on configuration. - - * res/values: integers, strings, etc. Each resource may have different - values depending on configuration. - -Resource meta information and information proper is stored in a binary -format in a named file resources.arsc, bundled as part of the .apk. - -Resource IDs and lookup -~~~~~~~~~~~~~~~~~~~~~~~ -During compilation, the aapt tool gathers application resources and -generates a resources.arsc file. Each resource name is assigned an -integer ID 0xppttiii (translated to a symbolic name via R.java), where - - * pp: corresponds to the package namespace (details below). - - * tt: corresponds to the resource type (string, int, etc). Every - resource of the same type within the same package has the same - tt value, but depending on available types, the actual numerical - value may be different between packages. - - * iiii: sequential number, assigned in the order resources are found. - -Resource values are specified paired with a set of configuration -constraints (the default being the empty set), eg res/values-sv-port -which imposes restrictions on language (Swedish) and display orientation -(portrait). During lookup, every constraint set is matched against the -current configuration, and the value corresponding to the best matching -constraint set is returned (ResourceTypes.{h,cpp}). - -Parsing of resources.arsc is handled by ResourceTypes.cpp; this utility -is governed by AssetManager.cpp, which tracks loaded resources per -process. - -Assets are looked up by path and filename in AssetManager.cpp. The path -to resources in res/drawable are located by ResourceTypes.cpp and then -handled like assets by AssetManager.cpp. Other resources are handled -solely by ResourceTypes.cpp. - -Package ID as namespace -~~~~~~~~~~~~~~~~~~~~~~~ -The pp part of a resource ID defines a namespace. Android currently -defines two namespaces: - - * 0x01: system resources (pre-installed in framework-res.apk) - - * 0x7f: application resources (bundled in the application .apk) - -ResourceTypes.cpp supports package IDs between 0x01 and 0x7f -(inclusive); values outside this range are invalid. - -Each running (Dalvik) process is assigned a unique instance of -AssetManager, which in turn keeps a forest structure of loaded -resource.arsc files. Normally, this forest is structured as follows, -where mPackageMap is the internal vector employed in ResourceTypes.cpp. - -mPackageMap[0x00] -> system package -mPackageMap[0x01] -> NULL -mPackageMap[0x02] -> NULL -... -mPackageMap[0x7f - 2] -> NULL -mPackageMap[0x7f - 1] -> application package - - - -The resource overlay extension ------------------------------- - -The resource overlay mechanism aims to (partly) shadow and extend -existing resources with new values for defined and new configurations. -Technically, this is achieved by adding resource-only packages (called -overlay packages) to existing resource namespaces, like so: - -mPackageMap[0x00] -> system package -> system overlay package -mPackageMap[0x01] -> NULL -mPackageMap[0x02] -> NULL -... -mPackageMap[0x7f - 2] -> NULL -mPackageMap[0x7f - 1] -> application package -> overlay 1 -> overlay 2 - -The use of overlay resources is completely transparent to -applications; no additional resource identifiers are introduced, only -configuration/value pairs. Any number of overlay packages may be loaded -at a time; overlay packages are agnostic to what they target -- both -system and application resources are fair game. - -The package targeted by an overlay package is called the target or -original package. - -Resource overlay operates on symbolic resources names. Hence, to -override the string/str1 resources in a package, the overlay package -would include a resource also named string/str1. The end user does not -have to worry about the numeric resources IDs assigned by aapt, as this -is resolved automatically by the system. - -As of this writing, the use of resource overlay has not been fully -explored. Until it has, only OEMs are trusted to use resource overlay. -For this reason, overlay packages must reside in /system/overlay. - - -Resource ID mapping -~~~~~~~~~~~~~~~~~~~ -Resource identifiers must be coherent within the same namespace (ie -PackageGroup in ResourceTypes.cpp). Calling applications will refer to -resources using the IDs defined in the original package, but there is no -guarantee aapt has assigned the same ID to the corresponding resource in -an overlay package. To translate between the two, a resource ID mapping -{original ID -> overlay ID} is created during package installation -(PackageManagerService.java) and used during resource lookup. The -mapping is stored in /data/resource-cache, with a @idmap file name -suffix. - -The idmap file format is documented in a separate section, below. - - -Package management -~~~~~~~~~~~~~~~~~~ -Packages are managed by the PackageManagerService. Addition and removal -of packages are monitored via the inotify framework, exposed via -android.os.FileObserver. - -During initialization of a Dalvik process, ActivityThread.java requests -the process' AssetManager (by proxy, via AssetManager.java and JNI) -to load a list of packages. This list includes overlay packages, if -present. - -When a target package or a corresponding overlay package is installed, -the target package's process is stopped and a new idmap is generated. -This is similar to how applications are stopped when their packages are -upgraded. - - -Creating overlay packages -------------------------- - -Overlay packages should contain no code, define (some) resources with -the same type and name as in the original package, and be compiled with -the -o flag passed to aapt. - -The aapt -o flag instructs aapt to create an overlay package. -Technically, this means the package will be assigned package id 0x00. - -There are no restrictions on overlay packages names, though the naming -convention <original.package.name>.overlay.<name> is recommended. - - -Example overlay package -~~~~~~~~~~~~~~~~~~~~~~~ - -To overlay the resource bool/b in package com.foo.bar, to be applied -when the display is in landscape mode, create a new package with -no source code and a single .xml file under res/values-land, with -an entry for bool/b. Compile with aapt -o and place the results in -/system/overlay by adding the following to Android.mk: - -LOCAL_AAPT_FLAGS := -o com.foo.bar -LOCAL_MODULE_PATH := $(TARGET_OUT)/overlay - - -The ID map (idmap) file format ------------------------------- - -The idmap format is designed for lookup performance. However, leading -and trailing undefined overlay values are discarded to reduce the memory -footprint. - - -idmap grammar -~~~~~~~~~~~~~ -All atoms (names in square brackets) are uint32_t integers. The -idmap-magic constant spells "idmp" in ASCII. Offsets are given relative -to the data_header, not to the beginning of the file. - -map := header data -header := idmap-magic <crc32-original-pkg> <crc32-overlay-pkg> -idmap-magic := <0x706d6469> -data := data_header type_block+ -data_header := <m> header_block{m} -header_block := <0> | <type_block_offset> -type_block := <n> <id_offset> entry{n} -entry := <resource_id_in_target_package> - - -idmap example -~~~~~~~~~~~~~ -Given a pair of target and overlay packages with CRC sums 0x216a8fe2 -and 0x6b9beaec, each defining the following resources - -Name Target package Overlay package -string/str0 0x7f010000 - -string/str1 0x7f010001 0x7f010000 -string/str2 0x7f010002 - -string/str3 0x7f010003 0x7f010001 -string/str4 0x7f010004 - -bool/bool0 0x7f020000 - -integer/int0 0x7f030000 0x7f020000 -integer/int1 0x7f030001 - - -the corresponding resource map is - -0x706d6469 0x216a8fe2 0x6b9beaec 0x00000003 \ -0x00000004 0x00000000 0x00000009 0x00000003 \ -0x00000001 0x7f010000 0x00000000 0x7f010001 \ -0x00000001 0x00000000 0x7f020000 - -or, formatted differently - -0x706d6469 # magic: all idmap files begin with this constant -0x216a8fe2 # CRC32 of the resources.arsc file in the original package -0x6b9beaec # CRC32 of the resources.arsc file in the overlay package -0x00000003 # header; three types (string, bool, integer) in the target package -0x00000004 # header_block for type 0 (string) is located at offset 4 -0x00000000 # no bool type exists in overlay package -> no header_block -0x00000009 # header_block for type 2 (integer) is located at offset 9 -0x00000003 # header_block for string; overlay IDs span 3 elements -0x00000001 # the first string in target package is entry 1 == offset -0x7f010000 # target 0x7f01001 -> overlay 0x7f010000 -0x00000000 # str2 not defined in overlay package -0x7f010001 # target 0x7f010003 -> overlay 0x7f010001 -0x00000001 # header_block for integer; overlay IDs span 1 element -0x00000000 # offset == 0 -0x7f020000 # target 0x7f030000 -> overlay 0x7f020000 diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp deleted file mode 100644 index f398a82..0000000 --- a/libs/utils/RefBase.cpp +++ /dev/null @@ -1,650 +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/Atomic.h> -#include <utils/CallStack.h> -#include <utils/Log.h> -#include <utils/threads.h> - -#include <stdlib.h> -#include <stdio.h> -#include <typeinfo> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -// 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 { - -#define INITIAL_STRONG_VALUE (1<<28) - -// --------------------------------------------------------------------------- - -class RefBase::weakref_impl : public RefBase::weakref_type -{ -public: - volatile int32_t mStrong; - volatile int32_t mWeak; - RefBase* const mBase; - volatile int32_t mFlags; - -#if !DEBUG_REFS - - 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 ? '+' : '-'; - ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); -#if DEBUG_REFS_CALLSTACK_ENABLED - refs->stack.dump(LOG_TAG); -#endif - refs = refs->next; - } - } - - if (!mRetain && mWeakRefs != NULL) { - dumpStack = true; - ALOGE("Weak references remain!"); - ref_entry* refs = mWeakRefs; - while (refs) { - char inc = refs->ref >= 0 ? '+' : '-'; - ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); -#if DEBUG_REFS_CALLSTACK_ENABLED - refs->stack.dump(LOG_TAG); -#endif - refs = refs->next; - } - } - if (dumpStack) { - ALOGE("above errors at:"); - CallStack stack(LOG_TAG); - } - } - - void addStrongRef(const void* id) { - //ALOGD_IF(mTrackEnabled, - // "addStrongRef: RefBase=%p, id=%p", mBase, id); - addRef(&mStrongRefs, id, mStrong); - } - - 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); - } - } - - 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); - } - - void removeWeakRef(const void* id) { - if (!mRetain) { - removeRef(&mWeakRefs, id); - } else { - addRef(&mWeakRefs, id, -mWeak); - } - } - - 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]; - sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this); - text.append(buf); - printRefsLocked(&text, mStrongRefs); - sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this); - text.append(buf); - printRefsLocked(&text, mWeakRefs); - } - - { - char name[100]; - snprintf(name, 100, 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); - ALOGD("STACK TRACE for %p saved in %s", this, name); - } - else ALOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this, - name, strerror(errno)); - } - } - -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; - } - - ALOGE("RefBase: removing id %p on RefBase %p" - "(weakref_type %p) that doesn't exist!", - id, mBase, this); - - ref = head; - while (ref) { - char inc = ref->ref >= 0 ? '+' : '-'; - ALOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref); - 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 ? '+' : '-'; - sprintf(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 = android_atomic_inc(&refs->mStrong); - ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); -#if PRINT_REFS - ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c); -#endif - if (c != INITIAL_STRONG_VALUE) { - return; - } - - android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); - refs->mBase->onFirstRef(); -} - -void RefBase::decStrong(const void* id) const -{ - weakref_impl* const refs = mRefs; - refs->removeStrongRef(id); - const int32_t c = android_atomic_dec(&refs->mStrong); -#if PRINT_REFS - ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c); -#endif - ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs); - if (c == 1) { - refs->mBase->onLastStrongRef(id); - if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { - delete this; - } - } - refs->decWeak(id); -} - -void RefBase::forceIncStrong(const void* id) const -{ - weakref_impl* const refs = mRefs; - refs->incWeak(id); - - refs->addStrongRef(id); - const int32_t c = android_atomic_inc(&refs->mStrong); - ALOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow", - refs); -#if PRINT_REFS - ALOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c); -#endif - - switch (c) { - case INITIAL_STRONG_VALUE: - android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); - // fall through... - case 0: - refs->mBase->onFirstRef(); - } -} - -int32_t RefBase::getStrongCount() const -{ - return mRefs->mStrong; -} - -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 = android_atomic_inc(&impl->mWeak); - ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this); -} - - -void RefBase::weakref_type::decWeak(const void* id) -{ - weakref_impl* const impl = static_cast<weakref_impl*>(this); - impl->removeWeakRef(id); - const int32_t c = android_atomic_dec(&impl->mWeak); - ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this); - if (c != 1) return; - - if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) { - // This is the regular lifetime case. The object is destroyed - // when the last strong reference goes away. Since weakref_impl - // outlive the object, it is not destroyed in the dtor, and - // we'll have to do it here. - if (impl->mStrong == INITIAL_STRONG_VALUE) { - // Special case: we never had a strong reference, so we need to - // destroy the object now. - delete impl->mBase; - } else { - // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase); - delete impl; - } - } else { - // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER} - impl->mBase->onLastWeakRef(id); - if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) { - // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference - // is gone, we can destroy the object. - 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; - - ALOG_ASSERT(curCount >= 0, - "attemptIncStrong called on %p after underflow", this); - - 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 (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) { - break; - } - // the strong count has changed on us, we need to re-assert our - // situation. - curCount = impl->mStrong; - } - - 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 - if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == 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 (android_atomic_cmpxchg(curCount, curCount + 1, - &impl->mStrong) == 0) { - 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 = impl->mStrong; - } - - 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 = android_atomic_inc(&impl->mStrong); - } - - // 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 - ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount); -#endif - - // 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 = impl->mStrong; - while (curCount >= INITIAL_STRONG_VALUE) { - ALOG_ASSERT(curCount > INITIAL_STRONG_VALUE, - "attemptIncStrong in %p underflowed to INITIAL_STRONG_VALUE", - this); - if (android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE, - &impl->mStrong) == 0) { - break; - } - // the strong-count changed on us, we need to re-assert the situation, - // for e.g.: it's possible the fix-up happened in another thread. - curCount = impl->mStrong; - } - - return true; -} - -bool RefBase::weakref_type::attemptIncWeak(const void* id) -{ - weakref_impl* const impl = static_cast<weakref_impl*>(this); - - int32_t curCount = impl->mWeak; - ALOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow", - this); - while (curCount > 0) { - if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) { - break; - } - curCount = impl->mWeak; - } - - if (curCount > 0) { - impl->addWeakRef(id); - } - - return curCount > 0; -} - -int32_t RefBase::weakref_type::getWeakCount() const -{ - return static_cast<const weakref_impl*>(this)->mWeak; -} - -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() -{ - if (mRefs->mStrong == INITIAL_STRONG_VALUE) { - // we never acquired a strong (and/or weak) reference on this object. - delete mRefs; - } else { - // life-time of this object is extended to WEAK or FOREVER, in - // which case weakref_impl doesn't out-live the object and we - // can free it now. - if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) { - // It's possible that the weak count is not 0 if the object - // re-acquired a weak reference in its destructor - if (mRefs->mWeak == 0) { - delete mRefs; - } - } - } - // for debugging purposes, clear this. - const_cast<weakref_impl*&>(mRefs) = NULL; -} - -void RefBase::extendObjectLifetime(int32_t mode) -{ - android_atomic_or(mode, &mRefs->mFlags); -} - -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*/) -{ -} - -// --------------------------------------------------------------------------- - -void RefBase::renameRefs(size_t n, const ReferenceRenamer& renamer) { -#if DEBUG_REFS - for (size_t i=0 ; i<n ; i++) { - renamer(i); - } -#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/libs/utils/SharedBuffer.cpp b/libs/utils/SharedBuffer.cpp deleted file mode 100644 index 3555fb7..0000000 --- a/libs/utils/SharedBuffer.cpp +++ /dev/null @@ -1,113 +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. - */ - -#include <stdlib.h> -#include <string.h> - -#include <utils/SharedBuffer.h> -#include <utils/Atomic.h> - -// --------------------------------------------------------------------------- - -namespace android { - -SharedBuffer* SharedBuffer::alloc(size_t size) -{ - SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size)); - if (sb) { - sb->mRefs = 1; - sb->mSize = size; - } - return sb; -} - - -ssize_t SharedBuffer::dealloc(const SharedBuffer* released) -{ - if (released->mRefs != 0) return -1; // XXX: invalid operation - free(const_cast<SharedBuffer*>(released)); - return 0; -} - -SharedBuffer* SharedBuffer::edit() const -{ - if (onlyOwner()) { - return const_cast<SharedBuffer*>(this); - } - SharedBuffer* sb = alloc(mSize); - if (sb) { - memcpy(sb->data(), data(), size()); - release(); - } - return sb; -} - -SharedBuffer* SharedBuffer::editResize(size_t newSize) const -{ - if (onlyOwner()) { - SharedBuffer* buf = const_cast<SharedBuffer*>(this); - if (buf->mSize == newSize) return buf; - buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize); - if (buf != NULL) { - buf->mSize = newSize; - return buf; - } - } - SharedBuffer* sb = alloc(newSize); - if (sb) { - const size_t mySize = mSize; - memcpy(sb->data(), data(), newSize < mySize ? newSize : mySize); - release(); - } - return sb; -} - -SharedBuffer* SharedBuffer::attemptEdit() const -{ - if (onlyOwner()) { - return const_cast<SharedBuffer*>(this); - } - return 0; -} - -SharedBuffer* SharedBuffer::reset(size_t new_size) const -{ - // cheap-o-reset. - SharedBuffer* sb = alloc(new_size); - if (sb) { - release(); - } - return sb; -} - -void SharedBuffer::acquire() const { - android_atomic_inc(&mRefs); -} - -int32_t SharedBuffer::release(uint32_t flags) const -{ - int32_t prev = 1; - if (onlyOwner() || ((prev = android_atomic_dec(&mRefs)) == 1)) { - mRefs = 0; - if ((flags & eKeepStorage) == 0) { - free(const_cast<SharedBuffer*>(this)); - } - } - return prev; -} - - -}; // namespace android diff --git a/libs/utils/Static.cpp b/libs/utils/Static.cpp deleted file mode 100644 index 3ed07a1..0000000 --- a/libs/utils/Static.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2008 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. - */ - -// All static variables go here, to control initialization and -// destruction order in the library. - -namespace android { - -// For String8.cpp -extern void initialize_string8(); -extern void terminate_string8(); - -// For String16.cpp -extern void initialize_string16(); -extern void terminate_string16(); - -class LibUtilsFirstStatics -{ -public: - LibUtilsFirstStatics() - { - initialize_string8(); - initialize_string16(); - } - - ~LibUtilsFirstStatics() - { - terminate_string16(); - terminate_string8(); - } -}; - -static LibUtilsFirstStatics gFirstStatics; -int gDarwinCantLoadAllObjects = 1; - -} // namespace android diff --git a/libs/utils/StopWatch.cpp b/libs/utils/StopWatch.cpp deleted file mode 100644 index b1708d6..0000000 --- a/libs/utils/StopWatch.cpp +++ /dev/null @@ -1,88 +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 "StopWatch" - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> - -/* for PRId64 */ -#define __STDC_FORMAT_MACROS 1 -#include <inttypes.h> - -#include <utils/Log.h> -#include <utils/Errors.h> -#include <utils/StopWatch.h> - -/*****************************************************************************/ - -namespace android { - - -StopWatch::StopWatch(const char *name, int clock, uint32_t flags) - : mName(name), mClock(clock), mFlags(flags) -{ - reset(); -} - -StopWatch::~StopWatch() -{ - nsecs_t elapsed = elapsedTime(); - const int n = mNumLaps; - ALOGD("StopWatch %s (us): %" PRId64 " ", mName, ns2us(elapsed)); - for (int i=0 ; i<n ; i++) { - const nsecs_t soFar = mLaps[i].soFar; - const nsecs_t thisLap = mLaps[i].thisLap; - ALOGD(" [%d: %" PRId64 ", %" PRId64, i, ns2us(soFar), ns2us(thisLap)); - } -} - -const char* StopWatch::name() const -{ - return mName; -} - -nsecs_t StopWatch::lap() -{ - nsecs_t elapsed = elapsedTime(); - if (mNumLaps >= 8) { - elapsed = 0; - } else { - const int n = mNumLaps; - mLaps[n].soFar = elapsed; - mLaps[n].thisLap = n ? (elapsed - mLaps[n-1].soFar) : elapsed; - mNumLaps = n+1; - } - return elapsed; -} - -nsecs_t StopWatch::elapsedTime() const -{ - return systemTime(mClock) - mStartTime; -} - -void StopWatch::reset() -{ - mNumLaps = 0; - mStartTime = systemTime(mClock); -} - - -/*****************************************************************************/ - -}; // namespace android - diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp deleted file mode 100644 index b09b728..0000000 --- a/libs/utils/String16.cpp +++ /dev/null @@ -1,422 +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. - */ - -#include <utils/String16.h> - -#include <utils/Debug.h> -#include <utils/Log.h> -#include <utils/Unicode.h> -#include <utils/String8.h> -#include <utils/threads.h> - -#include <memory.h> -#include <stdio.h> -#include <ctype.h> - - -namespace android { - -static SharedBuffer* gEmptyStringBuf = NULL; -static char16_t* gEmptyString = NULL; - -static inline char16_t* getEmptyString() -{ - gEmptyStringBuf->acquire(); - return gEmptyString; -} - -void initialize_string16() -{ - SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t)); - char16_t* str = (char16_t*)buf->data(); - *str = 0; - gEmptyStringBuf = buf; - gEmptyString = str; -} - -void terminate_string16() -{ - SharedBuffer::bufferFromData(gEmptyString)->release(); - gEmptyStringBuf = NULL; - gEmptyString = NULL; -} - -// --------------------------------------------------------------------------- - -static char16_t* allocFromUTF8(const char* u8str, size_t u8len) -{ - if (u8len == 0) return getEmptyString(); - - const uint8_t* u8cur = (const uint8_t*) u8str; - - const ssize_t u16len = utf8_to_utf16_length(u8cur, u8len); - if (u16len < 0) { - return getEmptyString(); - } - - const uint8_t* const u8end = u8cur + u8len; - - SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t)*(u16len+1)); - if (buf) { - u8cur = (const uint8_t*) u8str; - char16_t* u16str = (char16_t*)buf->data(); - - utf8_to_utf16(u8cur, u8len, u16str); - - //printf("Created UTF-16 string from UTF-8 \"%s\":", in); - //printHexData(1, str, buf->size(), 16, 1); - //printf("\n"); - - return u16str; - } - - return getEmptyString(); -} - -// --------------------------------------------------------------------------- - -String16::String16() - : mString(getEmptyString()) -{ -} - -String16::String16(StaticLinkage) - : mString(0) -{ - // this constructor is used when we can't rely on the static-initializers - // having run. In this case we always allocate an empty string. It's less - // efficient than using getEmptyString(), but we assume it's uncommon. - - char16_t* data = static_cast<char16_t*>( - SharedBuffer::alloc(sizeof(char16_t))->data()); - data[0] = 0; - mString = data; -} - -String16::String16(const String16& o) - : mString(o.mString) -{ - SharedBuffer::bufferFromData(mString)->acquire(); -} - -String16::String16(const String16& o, size_t len, size_t begin) - : mString(getEmptyString()) -{ - setTo(o, len, begin); -} - -String16::String16(const char16_t* o) -{ - size_t len = strlen16(o); - SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t)); - ALOG_ASSERT(buf, "Unable to allocate shared buffer"); - if (buf) { - char16_t* str = (char16_t*)buf->data(); - strcpy16(str, o); - mString = str; - return; - } - - mString = getEmptyString(); -} - -String16::String16(const char16_t* o, size_t len) -{ - SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t)); - ALOG_ASSERT(buf, "Unable to allocate shared buffer"); - if (buf) { - char16_t* str = (char16_t*)buf->data(); - memcpy(str, o, len*sizeof(char16_t)); - str[len] = 0; - mString = str; - return; - } - - mString = getEmptyString(); -} - -String16::String16(const String8& o) - : mString(allocFromUTF8(o.string(), o.size())) -{ -} - -String16::String16(const char* o) - : mString(allocFromUTF8(o, strlen(o))) -{ -} - -String16::String16(const char* o, size_t len) - : mString(allocFromUTF8(o, len)) -{ -} - -String16::~String16() -{ - SharedBuffer::bufferFromData(mString)->release(); -} - -void String16::setTo(const String16& other) -{ - SharedBuffer::bufferFromData(other.mString)->acquire(); - SharedBuffer::bufferFromData(mString)->release(); - mString = other.mString; -} - -status_t String16::setTo(const String16& other, size_t len, size_t begin) -{ - const size_t N = other.size(); - if (begin >= N) { - SharedBuffer::bufferFromData(mString)->release(); - mString = getEmptyString(); - return NO_ERROR; - } - if ((begin+len) > N) len = N-begin; - if (begin == 0 && len == N) { - setTo(other); - return NO_ERROR; - } - - if (&other == this) { - LOG_ALWAYS_FATAL("Not implemented"); - } - - return setTo(other.string()+begin, len); -} - -status_t String16::setTo(const char16_t* other) -{ - return setTo(other, strlen16(other)); -} - -status_t String16::setTo(const char16_t* other, size_t len) -{ - SharedBuffer* buf = SharedBuffer::bufferFromData(mString) - ->editResize((len+1)*sizeof(char16_t)); - if (buf) { - char16_t* str = (char16_t*)buf->data(); - memmove(str, other, len*sizeof(char16_t)); - str[len] = 0; - mString = str; - return NO_ERROR; - } - return NO_MEMORY; -} - -status_t String16::append(const String16& other) -{ - const size_t myLen = size(); - const size_t otherLen = other.size(); - if (myLen == 0) { - setTo(other); - return NO_ERROR; - } else if (otherLen == 0) { - return NO_ERROR; - } - - SharedBuffer* buf = SharedBuffer::bufferFromData(mString) - ->editResize((myLen+otherLen+1)*sizeof(char16_t)); - if (buf) { - char16_t* str = (char16_t*)buf->data(); - memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t)); - mString = str; - return NO_ERROR; - } - return NO_MEMORY; -} - -status_t String16::append(const char16_t* chrs, size_t otherLen) -{ - const size_t myLen = size(); - if (myLen == 0) { - setTo(chrs, otherLen); - return NO_ERROR; - } else if (otherLen == 0) { - return NO_ERROR; - } - - SharedBuffer* buf = SharedBuffer::bufferFromData(mString) - ->editResize((myLen+otherLen+1)*sizeof(char16_t)); - if (buf) { - char16_t* str = (char16_t*)buf->data(); - memcpy(str+myLen, chrs, otherLen*sizeof(char16_t)); - str[myLen+otherLen] = 0; - mString = str; - return NO_ERROR; - } - return NO_MEMORY; -} - -status_t String16::insert(size_t pos, const char16_t* chrs) -{ - return insert(pos, chrs, strlen16(chrs)); -} - -status_t String16::insert(size_t pos, const char16_t* chrs, size_t len) -{ - const size_t myLen = size(); - if (myLen == 0) { - return setTo(chrs, len); - return NO_ERROR; - } else if (len == 0) { - return NO_ERROR; - } - - if (pos > myLen) pos = myLen; - - #if 0 - printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n", - String8(*this).string(), pos, - len, myLen, String8(chrs, len).string()); - #endif - - SharedBuffer* buf = SharedBuffer::bufferFromData(mString) - ->editResize((myLen+len+1)*sizeof(char16_t)); - if (buf) { - char16_t* str = (char16_t*)buf->data(); - if (pos < myLen) { - memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t)); - } - memcpy(str+pos, chrs, len*sizeof(char16_t)); - str[myLen+len] = 0; - mString = str; - #if 0 - printf("Result (%d chrs): %s\n", size(), String8(*this).string()); - #endif - return NO_ERROR; - } - return NO_MEMORY; -} - -ssize_t String16::findFirst(char16_t c) const -{ - const char16_t* str = string(); - const char16_t* p = str; - const char16_t* e = p + size(); - while (p < e) { - if (*p == c) { - return p-str; - } - p++; - } - return -1; -} - -ssize_t String16::findLast(char16_t c) const -{ - const char16_t* str = string(); - const char16_t* p = str; - const char16_t* e = p + size(); - while (p < e) { - e--; - if (*e == c) { - return e-str; - } - } - return -1; -} - -bool String16::startsWith(const String16& prefix) const -{ - const size_t ps = prefix.size(); - if (ps > size()) return false; - return strzcmp16(mString, ps, prefix.string(), ps) == 0; -} - -bool String16::startsWith(const char16_t* prefix) const -{ - const size_t ps = strlen16(prefix); - if (ps > size()) return false; - return strncmp16(mString, prefix, ps) == 0; -} - -status_t String16::makeLower() -{ - const size_t N = size(); - const char16_t* str = string(); - char16_t* edit = NULL; - for (size_t i=0; i<N; i++) { - const char16_t v = str[i]; - if (v >= 'A' && v <= 'Z') { - if (!edit) { - SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit(); - if (!buf) { - return NO_MEMORY; - } - edit = (char16_t*)buf->data(); - mString = str = edit; - } - edit[i] = tolower((char)v); - } - } - return NO_ERROR; -} - -status_t String16::replaceAll(char16_t replaceThis, char16_t withThis) -{ - const size_t N = size(); - const char16_t* str = string(); - char16_t* edit = NULL; - for (size_t i=0; i<N; i++) { - if (str[i] == replaceThis) { - if (!edit) { - SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit(); - if (!buf) { - return NO_MEMORY; - } - edit = (char16_t*)buf->data(); - mString = str = edit; - } - edit[i] = withThis; - } - } - return NO_ERROR; -} - -status_t String16::remove(size_t len, size_t begin) -{ - const size_t N = size(); - if (begin >= N) { - SharedBuffer::bufferFromData(mString)->release(); - mString = getEmptyString(); - return NO_ERROR; - } - if ((begin+len) > N) len = N-begin; - if (begin == 0 && len == N) { - return NO_ERROR; - } - - if (begin > 0) { - SharedBuffer* buf = SharedBuffer::bufferFromData(mString) - ->editResize((N+1)*sizeof(char16_t)); - if (!buf) { - return NO_MEMORY; - } - char16_t* str = (char16_t*)buf->data(); - memmove(str, str+begin, (N-begin+1)*sizeof(char16_t)); - mString = str; - } - SharedBuffer* buf = SharedBuffer::bufferFromData(mString) - ->editResize((len+1)*sizeof(char16_t)); - if (buf) { - char16_t* str = (char16_t*)buf->data(); - str[len] = 0; - mString = str; - return NO_ERROR; - } - return NO_MEMORY; -} - -}; // namespace android diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp deleted file mode 100644 index e852d77..0000000 --- a/libs/utils/String8.cpp +++ /dev/null @@ -1,640 +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. - */ - -#include <utils/String8.h> - -#include <utils/Log.h> -#include <utils/Unicode.h> -#include <utils/SharedBuffer.h> -#include <utils/String16.h> -#include <utils/threads.h> - -#include <ctype.h> - -/* - * Functions outside android is below the namespace android, since they use - * functions and constants in android namespace. - */ - -// --------------------------------------------------------------------------- - -namespace android { - -// Separator used by resource paths. This is not platform dependent contrary -// to OS_PATH_SEPARATOR. -#define RES_PATH_SEPARATOR '/' - -static SharedBuffer* gEmptyStringBuf = NULL; -static char* gEmptyString = NULL; - -extern int gDarwinCantLoadAllObjects; -int gDarwinIsReallyAnnoying; - -void initialize_string8(); - -static inline char* getEmptyString() -{ - gEmptyStringBuf->acquire(); - return gEmptyString; -} - -void initialize_string8() -{ - // HACK: This dummy dependency forces linking libutils Static.cpp, - // which is needed to initialize String8/String16 classes. - // These variables are named for Darwin, but are needed elsewhere too, - // including static linking on any platform. - gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects; - - SharedBuffer* buf = SharedBuffer::alloc(1); - char* str = (char*)buf->data(); - *str = 0; - gEmptyStringBuf = buf; - gEmptyString = str; -} - -void terminate_string8() -{ - SharedBuffer::bufferFromData(gEmptyString)->release(); - gEmptyStringBuf = NULL; - gEmptyString = NULL; -} - -// --------------------------------------------------------------------------- - -static char* allocFromUTF8(const char* in, size_t len) -{ - if (len > 0) { - SharedBuffer* buf = SharedBuffer::alloc(len+1); - ALOG_ASSERT(buf, "Unable to allocate shared buffer"); - if (buf) { - char* str = (char*)buf->data(); - memcpy(str, in, len); - str[len] = 0; - return str; - } - return NULL; - } - - return getEmptyString(); -} - -static char* allocFromUTF16(const char16_t* in, size_t len) -{ - if (len == 0) return getEmptyString(); - - const ssize_t bytes = utf16_to_utf8_length(in, len); - if (bytes < 0) { - return getEmptyString(); - } - - SharedBuffer* buf = SharedBuffer::alloc(bytes+1); - ALOG_ASSERT(buf, "Unable to allocate shared buffer"); - if (!buf) { - return getEmptyString(); - } - - char* str = (char*)buf->data(); - utf16_to_utf8(in, len, str); - return str; -} - -static char* allocFromUTF32(const char32_t* in, size_t len) -{ - if (len == 0) { - return getEmptyString(); - } - - const ssize_t bytes = utf32_to_utf8_length(in, len); - if (bytes < 0) { - return getEmptyString(); - } - - SharedBuffer* buf = SharedBuffer::alloc(bytes+1); - ALOG_ASSERT(buf, "Unable to allocate shared buffer"); - if (!buf) { - return getEmptyString(); - } - - char* str = (char*) buf->data(); - utf32_to_utf8(in, len, str); - - return str; -} - -// --------------------------------------------------------------------------- - -String8::String8() - : mString(getEmptyString()) -{ -} - -String8::String8(StaticLinkage) - : mString(0) -{ - // this constructor is used when we can't rely on the static-initializers - // having run. In this case we always allocate an empty string. It's less - // efficient than using getEmptyString(), but we assume it's uncommon. - - char* data = static_cast<char*>( - SharedBuffer::alloc(sizeof(char))->data()); - data[0] = 0; - mString = data; -} - -String8::String8(const String8& o) - : mString(o.mString) -{ - SharedBuffer::bufferFromData(mString)->acquire(); -} - -String8::String8(const char* o) - : mString(allocFromUTF8(o, strlen(o))) -{ - if (mString == NULL) { - mString = getEmptyString(); - } -} - -String8::String8(const char* o, size_t len) - : mString(allocFromUTF8(o, len)) -{ - if (mString == NULL) { - mString = getEmptyString(); - } -} - -String8::String8(const String16& o) - : mString(allocFromUTF16(o.string(), o.size())) -{ -} - -String8::String8(const char16_t* o) - : mString(allocFromUTF16(o, strlen16(o))) -{ -} - -String8::String8(const char16_t* o, size_t len) - : mString(allocFromUTF16(o, len)) -{ -} - -String8::String8(const char32_t* o) - : mString(allocFromUTF32(o, strlen32(o))) -{ -} - -String8::String8(const char32_t* o, size_t len) - : mString(allocFromUTF32(o, len)) -{ -} - -String8::~String8() -{ - SharedBuffer::bufferFromData(mString)->release(); -} - -String8 String8::format(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - - String8 result(formatV(fmt, args)); - - va_end(args); - return result; -} - -String8 String8::formatV(const char* fmt, va_list args) -{ - String8 result; - result.appendFormatV(fmt, args); - return result; -} - -void String8::clear() { - SharedBuffer::bufferFromData(mString)->release(); - mString = getEmptyString(); -} - -void String8::setTo(const String8& other) -{ - SharedBuffer::bufferFromData(other.mString)->acquire(); - SharedBuffer::bufferFromData(mString)->release(); - mString = other.mString; -} - -status_t String8::setTo(const char* other) -{ - const char *newString = allocFromUTF8(other, strlen(other)); - SharedBuffer::bufferFromData(mString)->release(); - mString = newString; - if (mString) return NO_ERROR; - - mString = getEmptyString(); - return NO_MEMORY; -} - -status_t String8::setTo(const char* other, size_t len) -{ - const char *newString = allocFromUTF8(other, len); - SharedBuffer::bufferFromData(mString)->release(); - mString = newString; - if (mString) return NO_ERROR; - - mString = getEmptyString(); - return NO_MEMORY; -} - -status_t String8::setTo(const char16_t* other, size_t len) -{ - const char *newString = allocFromUTF16(other, len); - SharedBuffer::bufferFromData(mString)->release(); - mString = newString; - if (mString) return NO_ERROR; - - mString = getEmptyString(); - return NO_MEMORY; -} - -status_t String8::setTo(const char32_t* other, size_t len) -{ - const char *newString = allocFromUTF32(other, len); - SharedBuffer::bufferFromData(mString)->release(); - mString = newString; - if (mString) return NO_ERROR; - - mString = getEmptyString(); - return NO_MEMORY; -} - -status_t String8::append(const String8& other) -{ - const size_t otherLen = other.bytes(); - if (bytes() == 0) { - setTo(other); - return NO_ERROR; - } else if (otherLen == 0) { - return NO_ERROR; - } - - return real_append(other.string(), otherLen); -} - -status_t String8::append(const char* other) -{ - return append(other, strlen(other)); -} - -status_t String8::append(const char* other, size_t otherLen) -{ - if (bytes() == 0) { - return setTo(other, otherLen); - } else if (otherLen == 0) { - return NO_ERROR; - } - - return real_append(other, otherLen); -} - -status_t String8::appendFormat(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - - status_t result = appendFormatV(fmt, args); - - va_end(args); - return result; -} - -status_t String8::appendFormatV(const char* fmt, va_list args) -{ - int result = NO_ERROR; - int n = vsnprintf(NULL, 0, fmt, args); - if (n != 0) { - size_t oldLength = length(); - char* buf = lockBuffer(oldLength + n); - if (buf) { - vsnprintf(buf + oldLength, n + 1, fmt, args); - } else { - result = NO_MEMORY; - } - } - return result; -} - -status_t String8::real_append(const char* other, size_t otherLen) -{ - const size_t myLen = bytes(); - - SharedBuffer* buf = SharedBuffer::bufferFromData(mString) - ->editResize(myLen+otherLen+1); - if (buf) { - char* str = (char*)buf->data(); - mString = str; - str += myLen; - memcpy(str, other, otherLen); - str[otherLen] = '\0'; - return NO_ERROR; - } - return NO_MEMORY; -} - -char* String8::lockBuffer(size_t size) -{ - SharedBuffer* buf = SharedBuffer::bufferFromData(mString) - ->editResize(size+1); - if (buf) { - char* str = (char*)buf->data(); - mString = str; - return str; - } - return NULL; -} - -void String8::unlockBuffer() -{ - unlockBuffer(strlen(mString)); -} - -status_t String8::unlockBuffer(size_t size) -{ - if (size != this->size()) { - SharedBuffer* buf = SharedBuffer::bufferFromData(mString) - ->editResize(size+1); - if (! buf) { - return NO_MEMORY; - } - - char* str = (char*)buf->data(); - str[size] = 0; - mString = str; - } - - return NO_ERROR; -} - -ssize_t String8::find(const char* other, size_t start) const -{ - size_t len = size(); - if (start >= len) { - return -1; - } - const char* s = mString+start; - const char* p = strstr(s, other); - return p ? p-mString : -1; -} - -void String8::toLower() -{ - toLower(0, size()); -} - -void String8::toLower(size_t start, size_t length) -{ - const size_t len = size(); - if (start >= len) { - return; - } - if (start+length > len) { - length = len-start; - } - char* buf = lockBuffer(len); - buf += start; - while (length > 0) { - *buf = tolower(*buf); - buf++; - length--; - } - unlockBuffer(len); -} - -void String8::toUpper() -{ - toUpper(0, size()); -} - -void String8::toUpper(size_t start, size_t length) -{ - const size_t len = size(); - if (start >= len) { - return; - } - if (start+length > len) { - length = len-start; - } - char* buf = lockBuffer(len); - buf += start; - while (length > 0) { - *buf = toupper(*buf); - buf++; - length--; - } - unlockBuffer(len); -} - -size_t String8::getUtf32Length() const -{ - return utf8_to_utf32_length(mString, length()); -} - -int32_t String8::getUtf32At(size_t index, size_t *next_index) const -{ - return utf32_from_utf8_at(mString, length(), index, next_index); -} - -void String8::getUtf32(char32_t* dst) const -{ - utf8_to_utf32(mString, length(), dst); -} - -// --------------------------------------------------------------------------- -// Path functions - -void String8::setPathName(const char* name) -{ - setPathName(name, strlen(name)); -} - -void String8::setPathName(const char* name, size_t len) -{ - char* buf = lockBuffer(len); - - memcpy(buf, name, len); - - // remove trailing path separator, if present - if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR) - len--; - - buf[len] = '\0'; - - unlockBuffer(len); -} - -String8 String8::getPathLeaf(void) const -{ - const char* cp; - const char*const buf = mString; - - cp = strrchr(buf, OS_PATH_SEPARATOR); - if (cp == NULL) - return String8(*this); - else - return String8(cp+1); -} - -String8 String8::getPathDir(void) const -{ - const char* cp; - const char*const str = mString; - - cp = strrchr(str, OS_PATH_SEPARATOR); - if (cp == NULL) - return String8(""); - else - return String8(str, cp - str); -} - -String8 String8::walkPath(String8* outRemains) const -{ - const char* cp; - const char*const str = mString; - const char* buf = str; - - cp = strchr(buf, OS_PATH_SEPARATOR); - if (cp == buf) { - // don't include a leading '/'. - buf = buf+1; - cp = strchr(buf, OS_PATH_SEPARATOR); - } - - if (cp == NULL) { - String8 res = buf != str ? String8(buf) : *this; - if (outRemains) *outRemains = String8(""); - return res; - } - - String8 res(buf, cp-buf); - if (outRemains) *outRemains = String8(cp+1); - return res; -} - -/* - * Helper function for finding the start of an extension in a pathname. - * - * Returns a pointer inside mString, or NULL if no extension was found. - */ -char* String8::find_extension(void) const -{ - const char* lastSlash; - const char* lastDot; - int extLen; - const char* const str = mString; - - // only look at the filename - lastSlash = strrchr(str, OS_PATH_SEPARATOR); - if (lastSlash == NULL) - lastSlash = str; - else - lastSlash++; - - // find the last dot - lastDot = strrchr(lastSlash, '.'); - if (lastDot == NULL) - return NULL; - - // looks good, ship it - return const_cast<char*>(lastDot); -} - -String8 String8::getPathExtension(void) const -{ - char* ext; - - ext = find_extension(); - if (ext != NULL) - return String8(ext); - else - return String8(""); -} - -String8 String8::getBasePath(void) const -{ - char* ext; - const char* const str = mString; - - ext = find_extension(); - if (ext == NULL) - return String8(*this); - else - return String8(str, ext - str); -} - -String8& String8::appendPath(const char* name) -{ - // TODO: The test below will fail for Win32 paths. Fix later or ignore. - if (name[0] != OS_PATH_SEPARATOR) { - if (*name == '\0') { - // nothing to do - return *this; - } - - size_t len = length(); - if (len == 0) { - // no existing filename, just use the new one - setPathName(name); - return *this; - } - - // make room for oldPath + '/' + newPath - int newlen = strlen(name); - - char* buf = lockBuffer(len+1+newlen); - - // insert a '/' if needed - if (buf[len-1] != OS_PATH_SEPARATOR) - buf[len++] = OS_PATH_SEPARATOR; - - memcpy(buf+len, name, newlen+1); - len += newlen; - - unlockBuffer(len); - - return *this; - } else { - setPathName(name); - return *this; - } -} - -String8& String8::convertToResPath() -{ -#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR - size_t len = length(); - if (len > 0) { - char * buf = lockBuffer(len); - for (char * end = buf + len; buf < end; ++buf) { - if (*buf == OS_PATH_SEPARATOR) - *buf = RES_PATH_SEPARATOR; - } - unlockBuffer(len); - } -#endif - return *this; -} - -}; // namespace android diff --git a/libs/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp deleted file mode 100644 index 4b74889..0000000 --- a/libs/utils/SystemClock.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2008 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. - */ - - -/* - * System clock functions. - */ - -#ifdef HAVE_ANDROID_OS -#include <linux/ioctl.h> -#include <linux/rtc.h> -#include <utils/Atomic.h> -#include <linux/android_alarm.h> -#endif - -#include <sys/time.h> -#include <limits.h> -#include <fcntl.h> -#include <errno.h> -#include <string.h> - -#include <utils/SystemClock.h> -#include <utils/Timers.h> - -#define LOG_TAG "SystemClock" -#include <utils/Log.h> - -namespace android { - -/* - * native public static long uptimeMillis(); - */ -int64_t uptimeMillis() -{ - int64_t when = systemTime(SYSTEM_TIME_MONOTONIC); - return (int64_t) nanoseconds_to_milliseconds(when); -} - -/* - * native public static long elapsedRealtime(); - */ -int64_t elapsedRealtime() -{ - return nanoseconds_to_milliseconds(elapsedRealtimeNano()); -} - -#define METHOD_CLOCK_GETTIME 0 -#define METHOD_IOCTL 1 -#define METHOD_SYSTEMTIME 2 - -static const char *gettime_method_names[] = { - "clock_gettime", - "ioctl", - "systemTime", -}; - -static inline void checkTimeStamps(int64_t timestamp, - int64_t volatile *prevTimestampPtr, - int volatile *prevMethodPtr, - int curMethod) -{ - /* - * Disable the check for SDK since the prebuilt toolchain doesn't contain - * gettid, and int64_t is different on the ARM platform - * (ie long vs long long). - */ -#ifdef ARCH_ARM - int64_t prevTimestamp = *prevTimestampPtr; - int prevMethod = *prevMethodPtr; - - if (timestamp < prevTimestamp) { - ALOGW("time going backwards: prev %lld(%s) vs now %lld(%s), tid=%d", - prevTimestamp, gettime_method_names[prevMethod], - timestamp, gettime_method_names[curMethod], - gettid()); - } - // NOTE - not atomic and may generate spurious warnings if the 64-bit - // write is interrupted or not observed as a whole. - *prevTimestampPtr = timestamp; - *prevMethodPtr = curMethod; -#endif -} - -/* - * native public static long elapsedRealtimeNano(); - */ -int64_t elapsedRealtimeNano() -{ -#ifdef HAVE_ANDROID_OS - struct timespec ts; - int result; - int64_t timestamp; - static volatile int64_t prevTimestamp; - static volatile int prevMethod; - -#if 0 - /* - * b/7100774 - * clock_gettime appears to have clock skews and can sometimes return - * backwards values. Disable its use until we find out what's wrong. - */ - result = clock_gettime(CLOCK_BOOTTIME, &ts); - if (result == 0) { - timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; - checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, - METHOD_CLOCK_GETTIME); - return timestamp; - } -#endif - - // CLOCK_BOOTTIME doesn't exist, fallback to /dev/alarm - static int s_fd = -1; - - if (s_fd == -1) { - int fd = open("/dev/alarm", O_RDONLY); - if (android_atomic_cmpxchg(-1, fd, &s_fd)) { - close(fd); - } - } - - result = ioctl(s_fd, - ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts); - - if (result == 0) { - timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; - checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL); - return timestamp; - } - - // XXX: there was an error, probably because the driver didn't - // exist ... this should return - // a real error, like an exception! - timestamp = systemTime(SYSTEM_TIME_MONOTONIC); - checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, - METHOD_SYSTEMTIME); - return timestamp; -#else - return systemTime(SYSTEM_TIME_MONOTONIC); -#endif -} - -}; // namespace android diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp deleted file mode 100644 index ff74914..0000000 --- a/libs/utils/Threads.cpp +++ /dev/null @@ -1,878 +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. - */ - -// #define LOG_NDEBUG 0 -#define LOG_TAG "libutils.threads" - -#include <utils/threads.h> -#include <utils/Log.h> - -#include <cutils/sched_policy.h> - -#include <stdio.h> -#include <stdlib.h> -#include <memory.h> -#include <errno.h> -#include <assert.h> -#include <unistd.h> - -#if defined(HAVE_PTHREADS) -# include <pthread.h> -# include <sched.h> -# include <sys/resource.h> -#ifdef HAVE_ANDROID_OS -# include <bionic_pthread.h> -#endif -#elif defined(HAVE_WIN32_THREADS) -# include <windows.h> -# include <stdint.h> -# include <process.h> -# define HAVE_CREATETHREAD // Cygwin, vs. HAVE__BEGINTHREADEX for MinGW -#endif - -#if defined(HAVE_PRCTL) -#include <sys/prctl.h> -#endif - -/* - * =========================================================================== - * Thread wrappers - * =========================================================================== - */ - -using namespace android; - -// ---------------------------------------------------------------------------- -#if defined(HAVE_PTHREADS) -// ---------------------------------------------------------------------------- - -/* - * Create and run a new thread. - * - * We create it "detached", so it cleans up after itself. - */ - -typedef void* (*android_pthread_entry)(void*); - -struct thread_data_t { - thread_func_t entryFunction; - void* userData; - int priority; - char * threadName; - - // we use this trampoline when we need to set the priority with - // nice/setpriority, and name with prctl. - static int trampoline(const thread_data_t* t) { - thread_func_t f = t->entryFunction; - void* u = t->userData; - int prio = t->priority; - char * name = t->threadName; - delete t; - setpriority(PRIO_PROCESS, 0, prio); - if (prio >= ANDROID_PRIORITY_BACKGROUND) { - set_sched_policy(0, SP_BACKGROUND); - } else { - set_sched_policy(0, SP_FOREGROUND); - } - - if (name) { - androidSetThreadName(name); - free(name); - } - return f(u); - } -}; - -void androidSetThreadName(const char* name) { -#if defined(HAVE_PRCTL) - // Mac OS doesn't have this, and we build libutil for the host too - int hasAt = 0; - int hasDot = 0; - const char *s = name; - while (*s) { - if (*s == '.') hasDot = 1; - else if (*s == '@') hasAt = 1; - s++; - } - int len = s - name; - if (len < 15 || hasAt || !hasDot) { - s = name; - } else { - s = name + len - 15; - } - prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0); -#endif -} - -int androidCreateRawThreadEtc(android_thread_func_t entryFunction, - void *userData, - const char* threadName, - int32_t threadPriority, - size_t threadStackSize, - android_thread_id_t *threadId) -{ - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - -#ifdef HAVE_ANDROID_OS /* valgrind is rejecting RT-priority create reqs */ - if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) { - // Now that the pthread_t has a method to find the associated - // android_thread_id_t (pid) from pthread_t, it would be possible to avoid - // this trampoline in some cases as the parent could set the properties - // for the child. However, there would be a race condition because the - // child becomes ready immediately, and it doesn't work for the name. - // prctl(PR_SET_NAME) only works for self; prctl(PR_SET_THREAD_NAME) was - // proposed but not yet accepted. - thread_data_t* t = new thread_data_t; - t->priority = threadPriority; - t->threadName = threadName ? strdup(threadName) : NULL; - t->entryFunction = entryFunction; - t->userData = userData; - entryFunction = (android_thread_func_t)&thread_data_t::trampoline; - userData = t; - } -#endif - - if (threadStackSize) { - pthread_attr_setstacksize(&attr, threadStackSize); - } - - errno = 0; - pthread_t thread; - int result = pthread_create(&thread, &attr, - (android_pthread_entry)entryFunction, userData); - pthread_attr_destroy(&attr); - if (result != 0) { - ALOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n" - "(android threadPriority=%d)", - entryFunction, result, errno, threadPriority); - return 0; - } - - // Note that *threadID is directly available to the parent only, as it is - // assigned after the child starts. Use memory barrier / lock if the child - // or other threads also need access. - if (threadId != NULL) { - *threadId = (android_thread_id_t)thread; // XXX: this is not portable - } - return 1; -} - -#ifdef HAVE_ANDROID_OS -static pthread_t android_thread_id_t_to_pthread(android_thread_id_t thread) -{ - return (pthread_t) thread; -} -#endif - -android_thread_id_t androidGetThreadId() -{ - return (android_thread_id_t)pthread_self(); -} - -// ---------------------------------------------------------------------------- -#elif defined(HAVE_WIN32_THREADS) -// ---------------------------------------------------------------------------- - -/* - * Trampoline to make us __stdcall-compliant. - * - * We're expected to delete "vDetails" when we're done. - */ -struct threadDetails { - int (*func)(void*); - void* arg; -}; -static __stdcall unsigned int threadIntermediary(void* vDetails) -{ - struct threadDetails* pDetails = (struct threadDetails*) vDetails; - int result; - - result = (*(pDetails->func))(pDetails->arg); - - delete pDetails; - - ALOG(LOG_VERBOSE, "thread", "thread exiting\n"); - return (unsigned int) result; -} - -/* - * Create and run a new thread. - */ -static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id) -{ - HANDLE hThread; - struct threadDetails* pDetails = new threadDetails; // must be on heap - unsigned int thrdaddr; - - pDetails->func = fn; - pDetails->arg = arg; - -#if defined(HAVE__BEGINTHREADEX) - hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0, - &thrdaddr); - if (hThread == 0) -#elif defined(HAVE_CREATETHREAD) - hThread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) threadIntermediary, - (void*) pDetails, 0, (DWORD*) &thrdaddr); - if (hThread == NULL) -#endif - { - ALOG(LOG_WARN, "thread", "WARNING: thread create failed\n"); - return false; - } - -#if defined(HAVE_CREATETHREAD) - /* close the management handle */ - CloseHandle(hThread); -#endif - - if (id != NULL) { - *id = (android_thread_id_t)thrdaddr; - } - - return true; -} - -int androidCreateRawThreadEtc(android_thread_func_t fn, - void *userData, - const char* threadName, - int32_t threadPriority, - size_t threadStackSize, - android_thread_id_t *threadId) -{ - return doCreateThread( fn, userData, threadId); -} - -android_thread_id_t androidGetThreadId() -{ - return (android_thread_id_t)GetCurrentThreadId(); -} - -// ---------------------------------------------------------------------------- -#else -#error "Threads not supported" -#endif - -// ---------------------------------------------------------------------------- - -int androidCreateThread(android_thread_func_t fn, void* arg) -{ - return createThreadEtc(fn, arg); -} - -int androidCreateThreadGetID(android_thread_func_t fn, void *arg, android_thread_id_t *id) -{ - return createThreadEtc(fn, arg, "android:unnamed_thread", - PRIORITY_DEFAULT, 0, id); -} - -static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc; - -int androidCreateThreadEtc(android_thread_func_t entryFunction, - void *userData, - const char* threadName, - int32_t threadPriority, - size_t threadStackSize, - android_thread_id_t *threadId) -{ - return gCreateThreadFn(entryFunction, userData, threadName, - threadPriority, threadStackSize, threadId); -} - -void androidSetCreateThreadFunc(android_create_thread_fn func) -{ - gCreateThreadFn = func; -} - -pid_t androidGetTid() -{ -#ifdef HAVE_GETTID - return gettid(); -#else - return getpid(); -#endif -} - -#ifdef HAVE_ANDROID_OS -int androidSetThreadPriority(pid_t tid, int pri) -{ - int rc = 0; - -#if defined(HAVE_PTHREADS) - int lasterr = 0; - - if (pri >= ANDROID_PRIORITY_BACKGROUND) { - rc = set_sched_policy(tid, SP_BACKGROUND); - } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) { - rc = set_sched_policy(tid, SP_FOREGROUND); - } - - if (rc) { - lasterr = errno; - } - - if (setpriority(PRIO_PROCESS, tid, pri) < 0) { - rc = INVALID_OPERATION; - } else { - errno = lasterr; - } -#endif - - return rc; -} - -int androidGetThreadPriority(pid_t tid) { -#if defined(HAVE_PTHREADS) - return getpriority(PRIO_PROCESS, tid); -#else - return ANDROID_PRIORITY_NORMAL; -#endif -} - -#endif - -namespace android { - -/* - * =========================================================================== - * Mutex class - * =========================================================================== - */ - -#if defined(HAVE_PTHREADS) -// implemented as inlines in threads.h -#elif defined(HAVE_WIN32_THREADS) - -Mutex::Mutex() -{ - HANDLE hMutex; - - assert(sizeof(hMutex) == sizeof(mState)); - - hMutex = CreateMutex(NULL, FALSE, NULL); - mState = (void*) hMutex; -} - -Mutex::Mutex(const char* name) -{ - // XXX: name not used for now - HANDLE hMutex; - - assert(sizeof(hMutex) == sizeof(mState)); - - hMutex = CreateMutex(NULL, FALSE, NULL); - mState = (void*) hMutex; -} - -Mutex::Mutex(int type, const char* name) -{ - // XXX: type and name not used for now - HANDLE hMutex; - - assert(sizeof(hMutex) == sizeof(mState)); - - hMutex = CreateMutex(NULL, FALSE, NULL); - mState = (void*) hMutex; -} - -Mutex::~Mutex() -{ - CloseHandle((HANDLE) mState); -} - -status_t Mutex::lock() -{ - DWORD dwWaitResult; - dwWaitResult = WaitForSingleObject((HANDLE) mState, INFINITE); - return dwWaitResult != WAIT_OBJECT_0 ? -1 : NO_ERROR; -} - -void Mutex::unlock() -{ - if (!ReleaseMutex((HANDLE) mState)) - ALOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n"); -} - -status_t Mutex::tryLock() -{ - DWORD dwWaitResult; - - dwWaitResult = WaitForSingleObject((HANDLE) mState, 0); - if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT) - ALOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n"); - return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1; -} - -#else -#error "Somebody forgot to implement threads for this platform." -#endif - - -/* - * =========================================================================== - * Condition class - * =========================================================================== - */ - -#if defined(HAVE_PTHREADS) -// implemented as inlines in threads.h -#elif defined(HAVE_WIN32_THREADS) - -/* - * Windows doesn't have a condition variable solution. It's possible - * to create one, but it's easy to get it wrong. For a discussion, and - * the origin of this implementation, see: - * - * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html - * - * The implementation shown on the page does NOT follow POSIX semantics. - * As an optimization they require acquiring the external mutex before - * calling signal() and broadcast(), whereas POSIX only requires grabbing - * it before calling wait(). The implementation here has been un-optimized - * to have the correct behavior. - */ -typedef struct WinCondition { - // Number of waiting threads. - int waitersCount; - - // Serialize access to waitersCount. - CRITICAL_SECTION waitersCountLock; - - // Semaphore used to queue up threads waiting for the condition to - // become signaled. - HANDLE sema; - - // An auto-reset event used by the broadcast/signal thread to wait - // for all the waiting thread(s) to wake up and be released from - // the semaphore. - HANDLE waitersDone; - - // This mutex wouldn't be necessary if we required that the caller - // lock the external mutex before calling signal() and broadcast(). - // I'm trying to mimic pthread semantics though. - HANDLE internalMutex; - - // Keeps track of whether we were broadcasting or signaling. This - // allows us to optimize the code if we're just signaling. - bool wasBroadcast; - - status_t wait(WinCondition* condState, HANDLE hMutex, nsecs_t* abstime) - { - // Increment the wait count, avoiding race conditions. - EnterCriticalSection(&condState->waitersCountLock); - condState->waitersCount++; - //printf("+++ wait: incr waitersCount to %d (tid=%ld)\n", - // condState->waitersCount, getThreadId()); - LeaveCriticalSection(&condState->waitersCountLock); - - DWORD timeout = INFINITE; - if (abstime) { - nsecs_t reltime = *abstime - systemTime(); - if (reltime < 0) - reltime = 0; - timeout = reltime/1000000; - } - - // Atomically release the external mutex and wait on the semaphore. - DWORD res = - SignalObjectAndWait(hMutex, condState->sema, timeout, FALSE); - - //printf("+++ wait: awake (tid=%ld)\n", getThreadId()); - - // Reacquire lock to avoid race conditions. - EnterCriticalSection(&condState->waitersCountLock); - - // No longer waiting. - condState->waitersCount--; - - // Check to see if we're the last waiter after a broadcast. - bool lastWaiter = (condState->wasBroadcast && condState->waitersCount == 0); - - //printf("+++ wait: lastWaiter=%d (wasBc=%d wc=%d)\n", - // lastWaiter, condState->wasBroadcast, condState->waitersCount); - - LeaveCriticalSection(&condState->waitersCountLock); - - // If we're the last waiter thread during this particular broadcast - // then signal broadcast() that we're all awake. It'll drop the - // internal mutex. - if (lastWaiter) { - // Atomically signal the "waitersDone" event and wait until we - // can acquire the internal mutex. We want to do this in one step - // because it ensures that everybody is in the mutex FIFO before - // any thread has a chance to run. Without it, another thread - // could wake up, do work, and hop back in ahead of us. - SignalObjectAndWait(condState->waitersDone, condState->internalMutex, - INFINITE, FALSE); - } else { - // Grab the internal mutex. - WaitForSingleObject(condState->internalMutex, INFINITE); - } - - // Release the internal and grab the external. - ReleaseMutex(condState->internalMutex); - WaitForSingleObject(hMutex, INFINITE); - - return res == WAIT_OBJECT_0 ? NO_ERROR : -1; - } -} WinCondition; - -/* - * Constructor. Set up the WinCondition stuff. - */ -Condition::Condition() -{ - WinCondition* condState = new WinCondition; - - condState->waitersCount = 0; - condState->wasBroadcast = false; - // semaphore: no security, initial value of 0 - condState->sema = CreateSemaphore(NULL, 0, 0x7fffffff, NULL); - InitializeCriticalSection(&condState->waitersCountLock); - // auto-reset event, not signaled initially - condState->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL); - // used so we don't have to lock external mutex on signal/broadcast - condState->internalMutex = CreateMutex(NULL, FALSE, NULL); - - mState = condState; -} - -/* - * Destructor. Free Windows resources as well as our allocated storage. - */ -Condition::~Condition() -{ - WinCondition* condState = (WinCondition*) mState; - if (condState != NULL) { - CloseHandle(condState->sema); - CloseHandle(condState->waitersDone); - delete condState; - } -} - - -status_t Condition::wait(Mutex& mutex) -{ - WinCondition* condState = (WinCondition*) mState; - HANDLE hMutex = (HANDLE) mutex.mState; - - return ((WinCondition*)mState)->wait(condState, hMutex, NULL); -} - -status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) -{ - WinCondition* condState = (WinCondition*) mState; - HANDLE hMutex = (HANDLE) mutex.mState; - nsecs_t absTime = systemTime()+reltime; - - return ((WinCondition*)mState)->wait(condState, hMutex, &absTime); -} - -/* - * Signal the condition variable, allowing one thread to continue. - */ -void Condition::signal() -{ - WinCondition* condState = (WinCondition*) mState; - - // Lock the internal mutex. This ensures that we don't clash with - // broadcast(). - WaitForSingleObject(condState->internalMutex, INFINITE); - - EnterCriticalSection(&condState->waitersCountLock); - bool haveWaiters = (condState->waitersCount > 0); - LeaveCriticalSection(&condState->waitersCountLock); - - // If no waiters, then this is a no-op. Otherwise, knock the semaphore - // down a notch. - if (haveWaiters) - ReleaseSemaphore(condState->sema, 1, 0); - - // Release internal mutex. - ReleaseMutex(condState->internalMutex); -} - -/* - * Signal the condition variable, allowing all threads to continue. - * - * First we have to wake up all threads waiting on the semaphore, then - * we wait until all of the threads have actually been woken before - * releasing the internal mutex. This ensures that all threads are woken. - */ -void Condition::broadcast() -{ - WinCondition* condState = (WinCondition*) mState; - - // Lock the internal mutex. This keeps the guys we're waking up - // from getting too far. - WaitForSingleObject(condState->internalMutex, INFINITE); - - EnterCriticalSection(&condState->waitersCountLock); - bool haveWaiters = false; - - if (condState->waitersCount > 0) { - haveWaiters = true; - condState->wasBroadcast = true; - } - - if (haveWaiters) { - // Wake up all the waiters. - ReleaseSemaphore(condState->sema, condState->waitersCount, 0); - - LeaveCriticalSection(&condState->waitersCountLock); - - // Wait for all awakened threads to acquire the counting semaphore. - // The last guy who was waiting sets this. - WaitForSingleObject(condState->waitersDone, INFINITE); - - // Reset wasBroadcast. (No crit section needed because nobody - // else can wake up to poke at it.) - condState->wasBroadcast = 0; - } else { - // nothing to do - LeaveCriticalSection(&condState->waitersCountLock); - } - - // Release internal mutex. - ReleaseMutex(condState->internalMutex); -} - -#else -#error "condition variables not supported on this platform" -#endif - -// ---------------------------------------------------------------------------- - -/* - * This is our thread object! - */ - -Thread::Thread(bool canCallJava) - : mCanCallJava(canCallJava), - mThread(thread_id_t(-1)), - mLock("Thread::mLock"), - mStatus(NO_ERROR), - mExitPending(false), mRunning(false) -#ifdef HAVE_ANDROID_OS - , mTid(-1) -#endif -{ -} - -Thread::~Thread() -{ -} - -status_t Thread::readyToRun() -{ - return NO_ERROR; -} - -status_t Thread::run(const char* name, int32_t priority, size_t stack) -{ - Mutex::Autolock _l(mLock); - - if (mRunning) { - // thread already started - return INVALID_OPERATION; - } - - // reset status and exitPending to their default value, so we can - // try again after an error happened (either below, or in readyToRun()) - mStatus = NO_ERROR; - mExitPending = false; - mThread = thread_id_t(-1); - - // hold a strong reference on ourself - mHoldSelf = this; - - mRunning = true; - - bool res; - if (mCanCallJava) { - res = createThreadEtc(_threadLoop, - this, name, priority, stack, &mThread); - } else { - res = androidCreateRawThreadEtc(_threadLoop, - this, name, priority, stack, &mThread); - } - - if (res == false) { - mStatus = UNKNOWN_ERROR; // something happened! - mRunning = false; - mThread = thread_id_t(-1); - mHoldSelf.clear(); // "this" may have gone away after this. - - return UNKNOWN_ERROR; - } - - // Do not refer to mStatus here: The thread is already running (may, in fact - // already have exited with a valid mStatus result). The NO_ERROR indication - // here merely indicates successfully starting the thread and does not - // imply successful termination/execution. - return NO_ERROR; - - // Exiting scope of mLock is a memory barrier and allows new thread to run -} - -int Thread::_threadLoop(void* user) -{ - Thread* const self = static_cast<Thread*>(user); - - sp<Thread> strong(self->mHoldSelf); - wp<Thread> weak(strong); - self->mHoldSelf.clear(); - -#ifdef HAVE_ANDROID_OS - // this is very useful for debugging with gdb - self->mTid = gettid(); -#endif - - bool first = true; - - do { - bool result; - if (first) { - first = false; - self->mStatus = self->readyToRun(); - result = (self->mStatus == NO_ERROR); - - if (result && !self->exitPending()) { - // Binder threads (and maybe others) rely on threadLoop - // running at least once after a successful ::readyToRun() - // (unless, of course, the thread has already been asked to exit - // at that point). - // This is because threads are essentially used like this: - // (new ThreadSubclass())->run(); - // The caller therefore does not retain a strong reference to - // the thread and the thread would simply disappear after the - // successful ::readyToRun() call instead of entering the - // threadLoop at least once. - result = self->threadLoop(); - } - } else { - result = self->threadLoop(); - } - - // establish a scope for mLock - { - Mutex::Autolock _l(self->mLock); - if (result == false || self->mExitPending) { - self->mExitPending = true; - self->mRunning = false; - // clear thread ID so that requestExitAndWait() does not exit if - // called by a new thread using the same thread ID as this one. - self->mThread = thread_id_t(-1); - // note that interested observers blocked in requestExitAndWait are - // awoken by broadcast, but blocked on mLock until break exits scope - self->mThreadExitedCondition.broadcast(); - break; - } - } - - // Release our strong reference, to let a chance to the thread - // to die a peaceful death. - strong.clear(); - // And immediately, re-acquire a strong reference for the next loop - strong = weak.promote(); - } while(strong != 0); - - return 0; -} - -void Thread::requestExit() -{ - Mutex::Autolock _l(mLock); - mExitPending = true; -} - -status_t Thread::requestExitAndWait() -{ - Mutex::Autolock _l(mLock); - if (mThread == getThreadId()) { - ALOGW( - "Thread (this=%p): don't call waitForExit() from this " - "Thread object's thread. It's a guaranteed deadlock!", - this); - - return WOULD_BLOCK; - } - - mExitPending = true; - - while (mRunning == true) { - mThreadExitedCondition.wait(mLock); - } - // This next line is probably not needed any more, but is being left for - // historical reference. Note that each interested party will clear flag. - mExitPending = false; - - return mStatus; -} - -status_t Thread::join() -{ - Mutex::Autolock _l(mLock); - if (mThread == getThreadId()) { - ALOGW( - "Thread (this=%p): don't call join() from this " - "Thread object's thread. It's a guaranteed deadlock!", - this); - - return WOULD_BLOCK; - } - - while (mRunning == true) { - mThreadExitedCondition.wait(mLock); - } - - return mStatus; -} - -bool Thread::isRunning() const { - Mutex::Autolock _l(mLock); - return mRunning; -} - -#ifdef HAVE_ANDROID_OS -pid_t Thread::getTid() const -{ - // mTid is not defined until the child initializes it, and the caller may need it earlier - Mutex::Autolock _l(mLock); - pid_t tid; - if (mRunning) { - pthread_t pthread = android_thread_id_t_to_pthread(mThread); - tid = __pthread_gettid(pthread); - } else { - ALOGW("Thread (this=%p): getTid() is undefined before run()", this); - tid = -1; - } - return tid; -} -#endif - -bool Thread::exitPending() const -{ - Mutex::Autolock _l(mLock); - return mExitPending; -} - - - -}; // namespace android diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp deleted file mode 100644 index 5293cd2..0000000 --- a/libs/utils/Timers.cpp +++ /dev/null @@ -1,72 +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. - */ - -// -// Timer functions. -// -#include <utils/Timers.h> -#include <utils/Log.h> - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <sys/time.h> -#include <time.h> -#include <errno.h> -#include <limits.h> - -#ifdef HAVE_WIN32_THREADS -#include <windows.h> -#endif - -nsecs_t systemTime(int clock) -{ -#if defined(HAVE_POSIX_CLOCKS) - static const clockid_t clocks[] = { - CLOCK_REALTIME, - CLOCK_MONOTONIC, - CLOCK_PROCESS_CPUTIME_ID, - CLOCK_THREAD_CPUTIME_ID, - CLOCK_BOOTTIME - }; - struct timespec t; - t.tv_sec = t.tv_nsec = 0; - clock_gettime(clocks[clock], &t); - return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec; -#else - // we don't support the clocks here. - struct timeval t; - t.tv_sec = t.tv_usec = 0; - gettimeofday(&t, NULL); - return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL; -#endif -} - -int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime) -{ - int timeoutDelayMillis; - if (timeoutTime > referenceTime) { - uint64_t timeoutDelay = uint64_t(timeoutTime - referenceTime); - if (timeoutDelay > uint64_t((INT_MAX - 1) * 1000000LL)) { - timeoutDelayMillis = -1; - } else { - timeoutDelayMillis = (timeoutDelay + 999999LL) / 1000000LL; - } - } else { - timeoutDelayMillis = 0; - } - return timeoutDelayMillis; -} diff --git a/libs/utils/Tokenizer.cpp b/libs/utils/Tokenizer.cpp deleted file mode 100644 index 7067533..0000000 --- a/libs/utils/Tokenizer.cpp +++ /dev/null @@ -1,175 +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. - */ - -#define LOG_TAG "Tokenizer" - -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <utils/Log.h> -#include <utils/Tokenizer.h> - -// Enables debug output for the tokenizer. -#define DEBUG_TOKENIZER 0 - - -namespace android { - -static inline bool isDelimiter(char ch, const char* delimiters) { - return strchr(delimiters, ch) != NULL; -} - -Tokenizer::Tokenizer(const String8& filename, FileMap* fileMap, char* buffer, - bool ownBuffer, size_t length) : - mFilename(filename), mFileMap(fileMap), - mBuffer(buffer), mOwnBuffer(ownBuffer), mLength(length), - mCurrent(buffer), mLineNumber(1) { -} - -Tokenizer::~Tokenizer() { - if (mFileMap) { - mFileMap->release(); - } - if (mOwnBuffer) { - delete[] mBuffer; - } -} - -status_t Tokenizer::open(const String8& filename, Tokenizer** outTokenizer) { - *outTokenizer = NULL; - - int result = NO_ERROR; - int fd = ::open(filename.string(), O_RDONLY); - if (fd < 0) { - result = -errno; - ALOGE("Error opening file '%s', %s.", filename.string(), strerror(errno)); - } else { - struct stat stat; - if (fstat(fd, &stat)) { - result = -errno; - ALOGE("Error getting size of file '%s', %s.", filename.string(), strerror(errno)); - } else { - size_t length = size_t(stat.st_size); - - FileMap* fileMap = new FileMap(); - bool ownBuffer = false; - char* buffer; - if (fileMap->create(NULL, fd, 0, length, true)) { - fileMap->advise(FileMap::SEQUENTIAL); - buffer = static_cast<char*>(fileMap->getDataPtr()); - } else { - fileMap->release(); - fileMap = NULL; - - // Fall back to reading into a buffer since we can't mmap files in sysfs. - // The length we obtained from stat is wrong too (it will always be 4096) - // so we must trust that read will read the entire file. - buffer = new char[length]; - ownBuffer = true; - ssize_t nrd = read(fd, buffer, length); - if (nrd < 0) { - result = -errno; - ALOGE("Error reading file '%s', %s.", filename.string(), strerror(errno)); - delete[] buffer; - buffer = NULL; - } else { - length = size_t(nrd); - } - } - - if (!result) { - *outTokenizer = new Tokenizer(filename, fileMap, buffer, ownBuffer, length); - } - } - close(fd); - } - return result; -} - -status_t Tokenizer::fromContents(const String8& filename, - const char* contents, Tokenizer** outTokenizer) { - *outTokenizer = new Tokenizer(filename, NULL, - const_cast<char*>(contents), false, strlen(contents)); - return OK; -} - -String8 Tokenizer::getLocation() const { - String8 result; - result.appendFormat("%s:%d", mFilename.string(), mLineNumber); - return result; -} - -String8 Tokenizer::peekRemainderOfLine() const { - const char* end = getEnd(); - const char* eol = mCurrent; - while (eol != end) { - char ch = *eol; - if (ch == '\n') { - break; - } - eol += 1; - } - return String8(mCurrent, eol - mCurrent); -} - -String8 Tokenizer::nextToken(const char* delimiters) { -#if DEBUG_TOKENIZER - ALOGD("nextToken"); -#endif - const char* end = getEnd(); - const char* tokenStart = mCurrent; - while (mCurrent != end) { - char ch = *mCurrent; - if (ch == '\n' || isDelimiter(ch, delimiters)) { - break; - } - mCurrent += 1; - } - return String8(tokenStart, mCurrent - tokenStart); -} - -void Tokenizer::nextLine() { -#if DEBUG_TOKENIZER - ALOGD("nextLine"); -#endif - const char* end = getEnd(); - while (mCurrent != end) { - char ch = *(mCurrent++); - if (ch == '\n') { - mLineNumber += 1; - break; - } - } -} - -void Tokenizer::skipDelimiters(const char* delimiters) { -#if DEBUG_TOKENIZER - ALOGD("skipDelimiters"); -#endif - const char* end = getEnd(); - while (mCurrent != end) { - char ch = *mCurrent; - if (ch == '\n' || !isDelimiter(ch, delimiters)) { - break; - } - mCurrent += 1; - } -} - -} // namespace android diff --git a/libs/utils/Trace.cpp b/libs/utils/Trace.cpp deleted file mode 100644 index 36fd802..0000000 --- a/libs/utils/Trace.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -#include <utils/misc.h> -#include <utils/Trace.h> - -static void traceInit() __attribute__((constructor)); - -static void traceInit() -{ - ::android::add_sysprop_change_callback(atrace_update_tags, 0); -} diff --git a/libs/utils/Unicode.cpp b/libs/utils/Unicode.cpp deleted file mode 100644 index 41cbf03..0000000 --- a/libs/utils/Unicode.cpp +++ /dev/null @@ -1,576 +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. - */ - -#include <utils/Unicode.h> - -#include <stddef.h> - -#ifdef HAVE_WINSOCK -# undef nhtol -# undef htonl -# undef nhtos -# undef htons - -# ifdef HAVE_LITTLE_ENDIAN -# define ntohl(x) ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) ) -# define htonl(x) ntohl(x) -# define ntohs(x) ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) ) -# define htons(x) ntohs(x) -# else -# define ntohl(x) (x) -# define htonl(x) (x) -# define ntohs(x) (x) -# define htons(x) (x) -# endif -#else -# include <netinet/in.h> -#endif - -extern "C" { - -static const char32_t kByteMask = 0x000000BF; -static const char32_t kByteMark = 0x00000080; - -// Surrogates aren't valid for UTF-32 characters, so define some -// constants that will let us screen them out. -static const char32_t kUnicodeSurrogateHighStart = 0x0000D800; -static const char32_t kUnicodeSurrogateHighEnd = 0x0000DBFF; -static const char32_t kUnicodeSurrogateLowStart = 0x0000DC00; -static const char32_t kUnicodeSurrogateLowEnd = 0x0000DFFF; -static const char32_t kUnicodeSurrogateStart = kUnicodeSurrogateHighStart; -static const char32_t kUnicodeSurrogateEnd = kUnicodeSurrogateLowEnd; -static const char32_t kUnicodeMaxCodepoint = 0x0010FFFF; - -// Mask used to set appropriate bits in first byte of UTF-8 sequence, -// indexed by number of bytes in the sequence. -// 0xxxxxxx -// -> (00-7f) 7bit. Bit mask for the first byte is 0x00000000 -// 110yyyyx 10xxxxxx -// -> (c0-df)(80-bf) 11bit. Bit mask is 0x000000C0 -// 1110yyyy 10yxxxxx 10xxxxxx -// -> (e0-ef)(80-bf)(80-bf) 16bit. Bit mask is 0x000000E0 -// 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx -// -> (f0-f7)(80-bf)(80-bf)(80-bf) 21bit. Bit mask is 0x000000F0 -static const char32_t kFirstByteMark[] = { - 0x00000000, 0x00000000, 0x000000C0, 0x000000E0, 0x000000F0 -}; - -// -------------------------------------------------------------------------- -// UTF-32 -// -------------------------------------------------------------------------- - -/** - * Return number of UTF-8 bytes required for the character. If the character - * is invalid, return size of 0. - */ -static inline size_t utf32_codepoint_utf8_length(char32_t srcChar) -{ - // Figure out how many bytes the result will require. - if (srcChar < 0x00000080) { - return 1; - } else if (srcChar < 0x00000800) { - return 2; - } else if (srcChar < 0x00010000) { - if ((srcChar < kUnicodeSurrogateStart) || (srcChar > kUnicodeSurrogateEnd)) { - return 3; - } else { - // Surrogates are invalid UTF-32 characters. - return 0; - } - } - // Max code point for Unicode is 0x0010FFFF. - else if (srcChar <= kUnicodeMaxCodepoint) { - return 4; - } else { - // Invalid UTF-32 character. - return 0; - } -} - -// Write out the source character to <dstP>. - -static inline void utf32_codepoint_to_utf8(uint8_t* dstP, char32_t srcChar, size_t bytes) -{ - dstP += bytes; - switch (bytes) - { /* note: everything falls through. */ - case 4: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6; - case 3: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6; - case 2: *--dstP = (uint8_t)((srcChar | kByteMark) & kByteMask); srcChar >>= 6; - case 1: *--dstP = (uint8_t)(srcChar | kFirstByteMark[bytes]); - } -} - -size_t strlen32(const char32_t *s) -{ - const char32_t *ss = s; - while ( *ss ) - ss++; - return ss-s; -} - -size_t strnlen32(const char32_t *s, size_t maxlen) -{ - const char32_t *ss = s; - while ((maxlen > 0) && *ss) { - ss++; - maxlen--; - } - return ss-s; -} - -static inline int32_t utf32_at_internal(const char* cur, size_t *num_read) -{ - const char first_char = *cur; - if ((first_char & 0x80) == 0) { // ASCII - *num_read = 1; - return *cur; - } - cur++; - char32_t mask, to_ignore_mask; - size_t num_to_read = 0; - char32_t utf32 = first_char; - for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0xFFFFFF80; - (first_char & mask); - num_to_read++, to_ignore_mask |= mask, mask >>= 1) { - // 0x3F == 00111111 - utf32 = (utf32 << 6) + (*cur++ & 0x3F); - } - to_ignore_mask |= mask; - utf32 &= ~(to_ignore_mask << (6 * (num_to_read - 1))); - - *num_read = num_to_read; - return static_cast<int32_t>(utf32); -} - -int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index) -{ - if (index >= src_len) { - return -1; - } - size_t dummy_index; - if (next_index == NULL) { - next_index = &dummy_index; - } - size_t num_read; - int32_t ret = utf32_at_internal(src + index, &num_read); - if (ret >= 0) { - *next_index = index + num_read; - } - - return ret; -} - -ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len) -{ - if (src == NULL || src_len == 0) { - return -1; - } - - size_t ret = 0; - const char32_t *end = src + src_len; - while (src < end) { - ret += utf32_codepoint_utf8_length(*src++); - } - return ret; -} - -void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst) -{ - if (src == NULL || src_len == 0 || dst == NULL) { - return; - } - - const char32_t *cur_utf32 = src; - const char32_t *end_utf32 = src + src_len; - char *cur = dst; - while (cur_utf32 < end_utf32) { - size_t len = utf32_codepoint_utf8_length(*cur_utf32); - utf32_codepoint_to_utf8((uint8_t *)cur, *cur_utf32++, len); - cur += len; - } - *cur = '\0'; -} - -// -------------------------------------------------------------------------- -// UTF-16 -// -------------------------------------------------------------------------- - -int strcmp16(const char16_t *s1, const char16_t *s2) -{ - char16_t ch; - int d = 0; - - while ( 1 ) { - d = (int)(ch = *s1++) - (int)*s2++; - if ( d || !ch ) - break; - } - - return d; -} - -int strncmp16(const char16_t *s1, const char16_t *s2, size_t n) -{ - char16_t ch; - int d = 0; - - while ( n-- ) { - d = (int)(ch = *s1++) - (int)*s2++; - if ( d || !ch ) - break; - } - - return d; -} - -char16_t *strcpy16(char16_t *dst, const char16_t *src) -{ - char16_t *q = dst; - const char16_t *p = src; - char16_t ch; - - do { - *q++ = ch = *p++; - } while ( ch ); - - return dst; -} - -size_t strlen16(const char16_t *s) -{ - const char16_t *ss = s; - while ( *ss ) - ss++; - return ss-s; -} - - -char16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n) -{ - char16_t *q = dst; - const char16_t *p = src; - char ch; - - while (n) { - n--; - *q++ = ch = *p++; - if ( !ch ) - break; - } - - *q = 0; - - return dst; -} - -size_t strnlen16(const char16_t *s, size_t maxlen) -{ - const char16_t *ss = s; - - /* Important: the maxlen test must precede the reference through ss; - since the byte beyond the maximum may segfault */ - while ((maxlen > 0) && *ss) { - ss++; - maxlen--; - } - return ss-s; -} - -int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2) -{ - const char16_t* e1 = s1+n1; - const char16_t* e2 = s2+n2; - - while (s1 < e1 && s2 < e2) { - const int d = (int)*s1++ - (int)*s2++; - if (d) { - return d; - } - } - - return n1 < n2 - ? (0 - (int)*s2) - : (n1 > n2 - ? ((int)*s1 - 0) - : 0); -} - -int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2) -{ - const char16_t* e1 = s1H+n1; - const char16_t* e2 = s2N+n2; - - while (s1H < e1 && s2N < e2) { - const char16_t c2 = ntohs(*s2N); - const int d = (int)*s1H++ - (int)c2; - s2N++; - if (d) { - return d; - } - } - - return n1 < n2 - ? (0 - (int)ntohs(*s2N)) - : (n1 > n2 - ? ((int)*s1H - 0) - : 0); -} - -void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst) -{ - if (src == NULL || src_len == 0 || dst == NULL) { - return; - } - - const char16_t* cur_utf16 = src; - const char16_t* const end_utf16 = src + src_len; - char *cur = dst; - while (cur_utf16 < end_utf16) { - char32_t utf32; - // surrogate pairs - if ((*cur_utf16 & 0xFC00) == 0xD800) { - utf32 = (*cur_utf16++ - 0xD800) << 10; - utf32 |= *cur_utf16++ - 0xDC00; - utf32 += 0x10000; - } else { - utf32 = (char32_t) *cur_utf16++; - } - const size_t len = utf32_codepoint_utf8_length(utf32); - utf32_codepoint_to_utf8((uint8_t*)cur, utf32, len); - cur += len; - } - *cur = '\0'; -} - -// -------------------------------------------------------------------------- -// UTF-8 -// -------------------------------------------------------------------------- - -ssize_t utf8_length(const char *src) -{ - const char *cur = src; - size_t ret = 0; - while (*cur != '\0') { - const char first_char = *cur++; - if ((first_char & 0x80) == 0) { // ASCII - ret += 1; - continue; - } - // (UTF-8's character must not be like 10xxxxxx, - // but 110xxxxx, 1110xxxx, ... or 1111110x) - if ((first_char & 0x40) == 0) { - return -1; - } - - int32_t mask, to_ignore_mask; - size_t num_to_read = 0; - char32_t utf32 = 0; - for (num_to_read = 1, mask = 0x40, to_ignore_mask = 0x80; - num_to_read < 5 && (first_char & mask); - num_to_read++, to_ignore_mask |= mask, mask >>= 1) { - if ((*cur & 0xC0) != 0x80) { // must be 10xxxxxx - return -1; - } - // 0x3F == 00111111 - utf32 = (utf32 << 6) + (*cur++ & 0x3F); - } - // "first_char" must be (110xxxxx - 11110xxx) - if (num_to_read == 5) { - return -1; - } - to_ignore_mask |= mask; - utf32 |= ((~to_ignore_mask) & first_char) << (6 * (num_to_read - 1)); - if (utf32 > kUnicodeMaxCodepoint) { - return -1; - } - - ret += num_to_read; - } - return ret; -} - -ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len) -{ - if (src == NULL || src_len == 0) { - return -1; - } - - size_t ret = 0; - const char16_t* const end = src + src_len; - while (src < end) { - if ((*src & 0xFC00) == 0xD800 && (src + 1) < end - && (*++src & 0xFC00) == 0xDC00) { - // surrogate pairs are always 4 bytes. - ret += 4; - src++; - } else { - ret += utf32_codepoint_utf8_length((char32_t) *src++); - } - } - return ret; -} - -/** - * Returns 1-4 based on the number of leading bits. - * - * 1111 -> 4 - * 1110 -> 3 - * 110x -> 2 - * 10xx -> 1 - * 0xxx -> 1 - */ -static inline size_t utf8_codepoint_len(uint8_t ch) -{ - return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1; -} - -static inline void utf8_shift_and_mask(uint32_t* codePoint, const uint8_t byte) -{ - *codePoint <<= 6; - *codePoint |= 0x3F & byte; -} - -size_t utf8_to_utf32_length(const char *src, size_t src_len) -{ - if (src == NULL || src_len == 0) { - return 0; - } - size_t ret = 0; - const char* cur; - const char* end; - size_t num_to_skip; - for (cur = src, end = src + src_len, num_to_skip = 1; - cur < end; - cur += num_to_skip, ret++) { - const char first_char = *cur; - num_to_skip = 1; - if ((first_char & 0x80) == 0) { // ASCII - continue; - } - int32_t mask; - - for (mask = 0x40; (first_char & mask); num_to_skip++, mask >>= 1) { - } - } - return ret; -} - -void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst) -{ - if (src == NULL || src_len == 0 || dst == NULL) { - return; - } - - const char* cur = src; - const char* const end = src + src_len; - char32_t* cur_utf32 = dst; - while (cur < end) { - size_t num_read; - *cur_utf32++ = static_cast<char32_t>(utf32_at_internal(cur, &num_read)); - cur += num_read; - } - *cur_utf32 = 0; -} - -static inline uint32_t utf8_to_utf32_codepoint(const uint8_t *src, size_t length) -{ - uint32_t unicode; - - switch (length) - { - case 1: - return src[0]; - case 2: - unicode = src[0] & 0x1f; - utf8_shift_and_mask(&unicode, src[1]); - return unicode; - case 3: - unicode = src[0] & 0x0f; - utf8_shift_and_mask(&unicode, src[1]); - utf8_shift_and_mask(&unicode, src[2]); - return unicode; - case 4: - unicode = src[0] & 0x07; - utf8_shift_and_mask(&unicode, src[1]); - utf8_shift_and_mask(&unicode, src[2]); - utf8_shift_and_mask(&unicode, src[3]); - return unicode; - default: - return 0xffff; - } - - //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result); -} - -ssize_t utf8_to_utf16_length(const uint8_t* u8str, size_t u8len) -{ - const uint8_t* const u8end = u8str + u8len; - const uint8_t* u8cur = u8str; - - /* Validate that the UTF-8 is the correct len */ - size_t u16measuredLen = 0; - while (u8cur < u8end) { - u16measuredLen++; - int u8charLen = utf8_codepoint_len(*u8cur); - uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8charLen); - if (codepoint > 0xFFFF) u16measuredLen++; // this will be a surrogate pair in utf16 - u8cur += u8charLen; - } - - /** - * Make sure that we ended where we thought we would and the output UTF-16 - * will be exactly how long we were told it would be. - */ - if (u8cur != u8end) { - return -1; - } - - return u16measuredLen; -} - -char16_t* utf8_to_utf16_no_null_terminator(const uint8_t* u8str, size_t u8len, char16_t* u16str) -{ - const uint8_t* const u8end = u8str + u8len; - const uint8_t* u8cur = u8str; - char16_t* u16cur = u16str; - - while (u8cur < u8end) { - size_t u8len = utf8_codepoint_len(*u8cur); - uint32_t codepoint = utf8_to_utf32_codepoint(u8cur, u8len); - - // Convert the UTF32 codepoint to one or more UTF16 codepoints - if (codepoint <= 0xFFFF) { - // Single UTF16 character - *u16cur++ = (char16_t) codepoint; - } else { - // Multiple UTF16 characters with surrogates - codepoint = codepoint - 0x10000; - *u16cur++ = (char16_t) ((codepoint >> 10) + 0xD800); - *u16cur++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00); - } - - u8cur += u8len; - } - return u16cur; -} - -void utf8_to_utf16(const uint8_t* u8str, size_t u8len, char16_t* u16str) { - char16_t* end = utf8_to_utf16_no_null_terminator(u8str, u8len, u16str); - *end = 0; -} - -} diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp deleted file mode 100644 index 5a79647..0000000 --- a/libs/utils/VectorImpl.cpp +++ /dev/null @@ -1,625 +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 "Vector" - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> - -#include <cutils/log.h> - -#include <utils/Errors.h> -#include <utils/SharedBuffer.h> -#include <utils/VectorImpl.h> - -/*****************************************************************************/ - - -namespace android { - -// ---------------------------------------------------------------------------- - -const size_t kMinVectorCapacity = 4; - -static inline size_t max(size_t a, size_t b) { - return a>b ? a : b; -} - -// ---------------------------------------------------------------------------- - -VectorImpl::VectorImpl(size_t itemSize, uint32_t flags) - : mStorage(0), mCount(0), mFlags(flags), mItemSize(itemSize) -{ -} - -VectorImpl::VectorImpl(const VectorImpl& rhs) - : mStorage(rhs.mStorage), mCount(rhs.mCount), - mFlags(rhs.mFlags), mItemSize(rhs.mItemSize) -{ - if (mStorage) { - SharedBuffer::bufferFromData(mStorage)->acquire(); - } -} - -VectorImpl::~VectorImpl() -{ - ALOGW_IF(mCount, - "[%p] subclasses of VectorImpl must call finish_vector()" - " in their destructor. Leaking %d bytes.", - this, (int)(mCount*mItemSize)); - // We can't call _do_destroy() here because the vtable is already gone. -} - -VectorImpl& VectorImpl::operator = (const VectorImpl& rhs) -{ - LOG_ALWAYS_FATAL_IF(mItemSize != rhs.mItemSize, - "Vector<> have different types (this=%p, rhs=%p)", this, &rhs); - if (this != &rhs) { - release_storage(); - if (rhs.mCount) { - mStorage = rhs.mStorage; - mCount = rhs.mCount; - SharedBuffer::bufferFromData(mStorage)->acquire(); - } else { - mStorage = 0; - mCount = 0; - } - } - return *this; -} - -void* VectorImpl::editArrayImpl() -{ - if (mStorage) { - SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage)->attemptEdit(); - if (sb == 0) { - sb = SharedBuffer::alloc(capacity() * mItemSize); - if (sb) { - _do_copy(sb->data(), mStorage, mCount); - release_storage(); - mStorage = sb->data(); - } - } - } - return mStorage; -} - -size_t VectorImpl::capacity() const -{ - if (mStorage) { - return SharedBuffer::bufferFromData(mStorage)->size() / mItemSize; - } - return 0; -} - -ssize_t VectorImpl::insertVectorAt(const VectorImpl& vector, size_t index) -{ - return insertArrayAt(vector.arrayImpl(), index, vector.size()); -} - -ssize_t VectorImpl::appendVector(const VectorImpl& vector) -{ - return insertVectorAt(vector, size()); -} - -ssize_t VectorImpl::insertArrayAt(const void* array, size_t index, size_t length) -{ - if (index > size()) - return BAD_INDEX; - void* where = _grow(index, length); - if (where) { - _do_copy(where, array, length); - } - return where ? index : (ssize_t)NO_MEMORY; -} - -ssize_t VectorImpl::appendArray(const void* array, size_t length) -{ - return insertArrayAt(array, size(), length); -} - -ssize_t VectorImpl::insertAt(size_t index, size_t numItems) -{ - return insertAt(0, index, numItems); -} - -ssize_t VectorImpl::insertAt(const void* item, size_t index, size_t numItems) -{ - if (index > size()) - return BAD_INDEX; - void* where = _grow(index, numItems); - if (where) { - if (item) { - _do_splat(where, item, numItems); - } else { - _do_construct(where, numItems); - } - } - return where ? index : (ssize_t)NO_MEMORY; -} - -static int sortProxy(const void* lhs, const void* rhs, void* func) -{ - return (*(VectorImpl::compar_t)func)(lhs, rhs); -} - -status_t VectorImpl::sort(VectorImpl::compar_t cmp) -{ - return sort(sortProxy, (void*)cmp); -} - -status_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state) -{ - // the sort must be stable. we're using insertion sort which - // is well suited for small and already sorted arrays - // for big arrays, it could be better to use mergesort - const ssize_t count = size(); - if (count > 1) { - void* array = const_cast<void*>(arrayImpl()); - void* temp = 0; - ssize_t i = 1; - while (i < count) { - void* item = reinterpret_cast<char*>(array) + mItemSize*(i); - void* curr = reinterpret_cast<char*>(array) + mItemSize*(i-1); - if (cmp(curr, item, state) > 0) { - - if (!temp) { - // we're going to have to modify the array... - array = editArrayImpl(); - if (!array) return NO_MEMORY; - temp = malloc(mItemSize); - if (!temp) return NO_MEMORY; - item = reinterpret_cast<char*>(array) + mItemSize*(i); - curr = reinterpret_cast<char*>(array) + mItemSize*(i-1); - } else { - _do_destroy(temp, 1); - } - - _do_copy(temp, item, 1); - - ssize_t j = i-1; - void* next = reinterpret_cast<char*>(array) + mItemSize*(i); - do { - _do_destroy(next, 1); - _do_copy(next, curr, 1); - next = curr; - --j; - curr = reinterpret_cast<char*>(array) + mItemSize*(j); - } while (j>=0 && (cmp(curr, temp, state) > 0)); - - _do_destroy(next, 1); - _do_copy(next, temp, 1); - } - i++; - } - - if (temp) { - _do_destroy(temp, 1); - free(temp); - } - } - return NO_ERROR; -} - -void VectorImpl::pop() -{ - if (size()) - removeItemsAt(size()-1, 1); -} - -void VectorImpl::push() -{ - push(0); -} - -void VectorImpl::push(const void* item) -{ - insertAt(item, size()); -} - -ssize_t VectorImpl::add() -{ - return add(0); -} - -ssize_t VectorImpl::add(const void* item) -{ - return insertAt(item, size()); -} - -ssize_t VectorImpl::replaceAt(size_t index) -{ - return replaceAt(0, index); -} - -ssize_t VectorImpl::replaceAt(const void* prototype, size_t index) -{ - ALOG_ASSERT(index<size(), - "[%p] replace: index=%d, size=%d", this, (int)index, (int)size()); - - if (index >= size()) { - return BAD_INDEX; - } - - void* item = editItemLocation(index); - if (item != prototype) { - if (item == 0) - return NO_MEMORY; - _do_destroy(item, 1); - if (prototype == 0) { - _do_construct(item, 1); - } else { - _do_copy(item, prototype, 1); - } - } - return ssize_t(index); -} - -ssize_t VectorImpl::removeItemsAt(size_t index, size_t count) -{ - ALOG_ASSERT((index+count)<=size(), - "[%p] remove: index=%d, count=%d, size=%d", - this, (int)index, (int)count, (int)size()); - - if ((index+count) > size()) - return BAD_VALUE; - _shrink(index, count); - return index; -} - -void VectorImpl::finish_vector() -{ - release_storage(); - mStorage = 0; - mCount = 0; -} - -void VectorImpl::clear() -{ - _shrink(0, mCount); -} - -void* VectorImpl::editItemLocation(size_t index) -{ - ALOG_ASSERT(index<capacity(), - "[%p] editItemLocation: index=%d, capacity=%d, count=%d", - this, (int)index, (int)capacity(), (int)mCount); - - if (index < capacity()) { - void* buffer = editArrayImpl(); - if (buffer) { - return reinterpret_cast<char*>(buffer) + index*mItemSize; - } - } - return 0; -} - -const void* VectorImpl::itemLocation(size_t index) const -{ - ALOG_ASSERT(index<capacity(), - "[%p] itemLocation: index=%d, capacity=%d, count=%d", - this, (int)index, (int)capacity(), (int)mCount); - - if (index < capacity()) { - const void* buffer = arrayImpl(); - if (buffer) { - return reinterpret_cast<const char*>(buffer) + index*mItemSize; - } - } - return 0; -} - -ssize_t VectorImpl::setCapacity(size_t new_capacity) -{ - size_t current_capacity = capacity(); - ssize_t amount = new_capacity - size(); - if (amount <= 0) { - // we can't reduce the capacity - return current_capacity; - } - SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); - if (sb) { - void* array = sb->data(); - _do_copy(array, mStorage, size()); - release_storage(); - mStorage = const_cast<void*>(array); - } else { - return NO_MEMORY; - } - return new_capacity; -} - -ssize_t VectorImpl::resize(size_t size) { - ssize_t result = NO_ERROR; - if (size > mCount) { - result = insertAt(mCount, size - mCount); - } else if (size < mCount) { - result = removeItemsAt(size, mCount - size); - } - return result < 0 ? result : size; -} - -void VectorImpl::release_storage() -{ - if (mStorage) { - const SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage); - if (sb->release(SharedBuffer::eKeepStorage) == 1) { - _do_destroy(mStorage, mCount); - SharedBuffer::dealloc(sb); - } - } -} - -void* VectorImpl::_grow(size_t where, size_t amount) -{ -// ALOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d", -// this, (int)where, (int)amount, (int)mCount, (int)capacity()); - - ALOG_ASSERT(where <= mCount, - "[%p] _grow: where=%d, amount=%d, count=%d", - this, (int)where, (int)amount, (int)mCount); // caller already checked - - const size_t new_size = mCount + amount; - if (capacity() < new_size) { - const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2); -// ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity); - if ((mStorage) && - (mCount==where) && - (mFlags & HAS_TRIVIAL_COPY) && - (mFlags & HAS_TRIVIAL_DTOR)) - { - const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); - SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); - mStorage = sb->data(); - } else { - SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); - if (sb) { - void* array = sb->data(); - if (where != 0) { - _do_copy(array, mStorage, where); - } - if (where != mCount) { - const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize; - void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; - _do_copy(dest, from, mCount-where); - } - release_storage(); - mStorage = const_cast<void*>(array); - } - } - } else { - void* array = editArrayImpl(); - if (where != mCount) { - const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize; - void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; - _do_move_forward(to, from, mCount - where); - } - } - mCount = new_size; - void* free_space = const_cast<void*>(itemLocation(where)); - return free_space; -} - -void VectorImpl::_shrink(size_t where, size_t amount) -{ - if (!mStorage) - return; - -// ALOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d", -// this, (int)where, (int)amount, (int)mCount, (int)capacity()); - - ALOG_ASSERT(where + amount <= mCount, - "[%p] _shrink: where=%d, amount=%d, count=%d", - this, (int)where, (int)amount, (int)mCount); // caller already checked - - const size_t new_size = mCount - amount; - if (new_size*3 < capacity()) { - const size_t new_capacity = max(kMinVectorCapacity, new_size*2); -// ALOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity); - if ((where == new_size) && - (mFlags & HAS_TRIVIAL_COPY) && - (mFlags & HAS_TRIVIAL_DTOR)) - { - const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); - SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); - mStorage = sb->data(); - } else { - SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); - if (sb) { - void* array = sb->data(); - if (where != 0) { - _do_copy(array, mStorage, where); - } - if (where != new_size) { - const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize; - void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize; - _do_copy(dest, from, new_size - where); - } - release_storage(); - mStorage = const_cast<void*>(array); - } - } - } else { - void* array = editArrayImpl(); - void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize; - _do_destroy(to, amount); - if (where != new_size) { - const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; - _do_move_backward(to, from, new_size - where); - } - } - mCount = new_size; -} - -size_t VectorImpl::itemSize() const { - return mItemSize; -} - -void VectorImpl::_do_construct(void* storage, size_t num) const -{ - if (!(mFlags & HAS_TRIVIAL_CTOR)) { - do_construct(storage, num); - } -} - -void VectorImpl::_do_destroy(void* storage, size_t num) const -{ - if (!(mFlags & HAS_TRIVIAL_DTOR)) { - do_destroy(storage, num); - } -} - -void VectorImpl::_do_copy(void* dest, const void* from, size_t num) const -{ - if (!(mFlags & HAS_TRIVIAL_COPY)) { - do_copy(dest, from, num); - } else { - memcpy(dest, from, num*itemSize()); - } -} - -void VectorImpl::_do_splat(void* dest, const void* item, size_t num) const { - do_splat(dest, item, num); -} - -void VectorImpl::_do_move_forward(void* dest, const void* from, size_t num) const { - do_move_forward(dest, from, num); -} - -void VectorImpl::_do_move_backward(void* dest, const void* from, size_t num) const { - do_move_backward(dest, from, num); -} - -/*****************************************************************************/ - -SortedVectorImpl::SortedVectorImpl(size_t itemSize, uint32_t flags) - : VectorImpl(itemSize, flags) -{ -} - -SortedVectorImpl::SortedVectorImpl(const VectorImpl& rhs) -: VectorImpl(rhs) -{ -} - -SortedVectorImpl::~SortedVectorImpl() -{ -} - -SortedVectorImpl& SortedVectorImpl::operator = (const SortedVectorImpl& rhs) -{ - return static_cast<SortedVectorImpl&>( VectorImpl::operator = (static_cast<const VectorImpl&>(rhs)) ); -} - -ssize_t SortedVectorImpl::indexOf(const void* item) const -{ - return _indexOrderOf(item); -} - -size_t SortedVectorImpl::orderOf(const void* item) const -{ - size_t o; - _indexOrderOf(item, &o); - return o; -} - -ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const -{ - // binary search - ssize_t err = NAME_NOT_FOUND; - ssize_t l = 0; - ssize_t h = size()-1; - ssize_t mid; - const void* a = arrayImpl(); - const size_t s = itemSize(); - while (l <= h) { - mid = l + (h - l)/2; - const void* const curr = reinterpret_cast<const char *>(a) + (mid*s); - const int c = do_compare(curr, item); - if (c == 0) { - err = l = mid; - break; - } else if (c < 0) { - l = mid + 1; - } else { - h = mid - 1; - } - } - if (order) *order = l; - return err; -} - -ssize_t SortedVectorImpl::add(const void* item) -{ - size_t order; - ssize_t index = _indexOrderOf(item, &order); - if (index < 0) { - index = VectorImpl::insertAt(item, order, 1); - } else { - index = VectorImpl::replaceAt(item, index); - } - return index; -} - -ssize_t SortedVectorImpl::merge(const VectorImpl& vector) -{ - // naive merge... - if (!vector.isEmpty()) { - const void* buffer = vector.arrayImpl(); - const size_t is = itemSize(); - size_t s = vector.size(); - for (size_t i=0 ; i<s ; i++) { - ssize_t err = add( reinterpret_cast<const char*>(buffer) + i*is ); - if (err<0) { - return err; - } - } - } - return NO_ERROR; -} - -ssize_t SortedVectorImpl::merge(const SortedVectorImpl& vector) -{ - // we've merging a sorted vector... nice! - ssize_t err = NO_ERROR; - if (!vector.isEmpty()) { - // first take care of the case where the vectors are sorted together - if (do_compare(vector.itemLocation(vector.size()-1), arrayImpl()) <= 0) { - err = VectorImpl::insertVectorAt(static_cast<const VectorImpl&>(vector), 0); - } else if (do_compare(vector.arrayImpl(), itemLocation(size()-1)) >= 0) { - err = VectorImpl::appendVector(static_cast<const VectorImpl&>(vector)); - } else { - // this could be made a little better - err = merge(static_cast<const VectorImpl&>(vector)); - } - } - return err; -} - -ssize_t SortedVectorImpl::remove(const void* item) -{ - ssize_t i = indexOf(item); - if (i>=0) { - VectorImpl::removeItemsAt(i, 1); - } - return i; -} - -/*****************************************************************************/ - -}; // namespace android - diff --git a/libs/utils/misc.cpp b/libs/utils/misc.cpp deleted file mode 100644 index 58eb499..0000000 --- a/libs/utils/misc.cpp +++ /dev/null @@ -1,90 +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 "misc" - -// -// Miscellaneous utility functions. -// -#include <utils/misc.h> -#include <utils/Log.h> - -#include <sys/stat.h> -#include <string.h> -#include <errno.h> -#include <stdio.h> - -#if defined(HAVE_PTHREADS) -# include <pthread.h> -#endif - -#include <utils/Vector.h> - -using namespace android; - -namespace android { - -struct sysprop_change_callback_info { - sysprop_change_callback callback; - int priority; -}; - -#if defined(HAVE_PTHREADS) -static pthread_mutex_t gSyspropMutex = PTHREAD_MUTEX_INITIALIZER; -static Vector<sysprop_change_callback_info>* gSyspropList = NULL; -#endif - -void add_sysprop_change_callback(sysprop_change_callback cb, int priority) { -#if defined(HAVE_PTHREADS) - pthread_mutex_lock(&gSyspropMutex); - if (gSyspropList == NULL) { - gSyspropList = new Vector<sysprop_change_callback_info>(); - } - sysprop_change_callback_info info; - info.callback = cb; - info.priority = priority; - bool added = false; - for (size_t i=0; i<gSyspropList->size(); i++) { - if (priority >= gSyspropList->itemAt(i).priority) { - gSyspropList->insertAt(info, i); - added = true; - break; - } - } - if (!added) { - gSyspropList->add(info); - } - pthread_mutex_unlock(&gSyspropMutex); -#endif -} - -void report_sysprop_change() { -#if defined(HAVE_PTHREADS) - pthread_mutex_lock(&gSyspropMutex); - Vector<sysprop_change_callback_info> listeners; - if (gSyspropList != NULL) { - listeners = *gSyspropList; - } - pthread_mutex_unlock(&gSyspropMutex); - - //ALOGI("Reporting sysprop change to %d listeners", listeners.size()); - for (size_t i=0; i<listeners.size(); i++) { - listeners[i].callback(); - } -#endif -} - -}; // namespace android diff --git a/libs/utils/primes.py b/libs/utils/primes.py deleted file mode 100755 index e161dd8..0000000 --- a/libs/utils/primes.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python2.6 -# -# Copyright (C) 2011 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. -# - -# -# Generates a table of prime numbers for use in BasicHashtable.cpp. -# -# Each prime is chosen such that it is a little more than twice as large as -# the previous prime in the table. This makes it easier to choose a new -# hashtable size when the underlying array is grown by as nominal factor -# of two each time. -# - -def is_odd_prime(n): - limit = (n - 1) / 2 - d = 3 - while d <= limit: - if n % d == 0: - return False - d += 2 - return True - -print "static size_t PRIMES[] = {" - -n = 5 -max = 2**31 - 1 -while n < max: - print " %d," % (n) - n = n * 2 + 1 - while not is_odd_prime(n): - n += 2 - -print " 0," -print "};" diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk deleted file mode 100644 index caedaff..0000000 --- a/libs/utils/tests/Android.mk +++ /dev/null @@ -1,34 +0,0 @@ -# Build the unit tests. -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -# Build the unit tests. -test_src_files := \ - BasicHashtable_test.cpp \ - BlobCache_test.cpp \ - BitSet_test.cpp \ - Looper_test.cpp \ - LruCache_test.cpp \ - String8_test.cpp \ - Unicode_test.cpp \ - Vector_test.cpp - -shared_libraries := \ - libz \ - liblog \ - libcutils \ - libutils \ - libstlport - -static_libraries := \ - libgtest \ - libgtest_main - -$(foreach file,$(test_src_files), \ - $(eval include $(CLEAR_VARS)) \ - $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \ - $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \ - $(eval LOCAL_SRC_FILES := $(file)) \ - $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \ - $(eval include $(BUILD_NATIVE_TEST)) \ -) diff --git a/libs/utils/tests/BasicHashtable_test.cpp b/libs/utils/tests/BasicHashtable_test.cpp deleted file mode 100644 index 7dcf750..0000000 --- a/libs/utils/tests/BasicHashtable_test.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Copyright (C) 2011 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 "BasicHashtable_test" - -#include <utils/BasicHashtable.h> -#include <cutils/log.h> -#include <gtest/gtest.h> -#include <unistd.h> - -namespace android { - -typedef int SimpleKey; -typedef int SimpleValue; -typedef key_value_pair_t<SimpleKey, SimpleValue> SimpleEntry; -typedef BasicHashtable<SimpleKey, SimpleEntry> SimpleHashtable; - -struct ComplexKey { - int k; - - explicit ComplexKey(int k) : k(k) { - instanceCount += 1; - } - - ComplexKey(const ComplexKey& other) : k(other.k) { - instanceCount += 1; - } - - ~ComplexKey() { - instanceCount -= 1; - } - - bool operator ==(const ComplexKey& other) const { - return k == other.k; - } - - bool operator !=(const ComplexKey& other) const { - return k != other.k; - } - - static ssize_t instanceCount; -}; - -ssize_t ComplexKey::instanceCount = 0; - -template<> inline hash_t hash_type(const ComplexKey& value) { - return hash_type(value.k); -} - -struct ComplexValue { - int v; - - explicit ComplexValue(int v) : v(v) { - instanceCount += 1; - } - - ComplexValue(const ComplexValue& other) : v(other.v) { - instanceCount += 1; - } - - ~ComplexValue() { - instanceCount -= 1; - } - - static ssize_t instanceCount; -}; - -ssize_t ComplexValue::instanceCount = 0; - -typedef key_value_pair_t<ComplexKey, ComplexValue> ComplexEntry; -typedef BasicHashtable<ComplexKey, ComplexEntry> ComplexHashtable; - -class BasicHashtableTest : public testing::Test { -protected: - virtual void SetUp() { - ComplexKey::instanceCount = 0; - ComplexValue::instanceCount = 0; - } - - virtual void TearDown() { - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); - } - - void assertInstanceCount(ssize_t keys, ssize_t values) { - if (keys != ComplexKey::instanceCount || values != ComplexValue::instanceCount) { - FAIL() << "Expected " << keys << " keys and " << values << " values " - "but there were actually " << ComplexKey::instanceCount << " keys and " - << ComplexValue::instanceCount << " values"; - } - } - -public: - template <typename TKey, typename TEntry> - static void cookieAt(const BasicHashtable<TKey, TEntry>& h, size_t index, - bool* collision, bool* present, hash_t* hash) { - uint32_t cookie = h.cookieAt(index); - *collision = cookie & BasicHashtable<TKey, TEntry>::Bucket::COLLISION; - *present = cookie & BasicHashtable<TKey, TEntry>::Bucket::PRESENT; - *hash = cookie & BasicHashtable<TKey, TEntry>::Bucket::HASH_MASK; - } - - template <typename TKey, typename TEntry> - static const void* getBuckets(const BasicHashtable<TKey, TEntry>& h) { - return h.mBuckets; - } -}; - -template <typename TKey, typename TValue> -static size_t add(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h, - const TKey& key, const TValue& value) { - return h.add(hash_type(key), key_value_pair_t<TKey, TValue>(key, value)); -} - -template <typename TKey, typename TValue> -static ssize_t find(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h, - ssize_t index, const TKey& key) { - return h.find(index, hash_type(key), key); -} - -template <typename TKey, typename TValue> -static bool remove(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h, - const TKey& key) { - ssize_t index = find(h, -1, key); - if (index >= 0) { - h.removeAt(index); - return true; - } - return false; -} - -template <typename TEntry> -static void getKeyValue(const TEntry& entry, int* key, int* value); - -template <> void getKeyValue(const SimpleEntry& entry, int* key, int* value) { - *key = entry.key; - *value = entry.value; -} - -template <> void getKeyValue(const ComplexEntry& entry, int* key, int* value) { - *key = entry.key.k; - *value = entry.value.v; -} - -template <typename TKey, typename TValue> -static void dump(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h) { - ALOGD("hashtable %p, size=%u, capacity=%u, bucketCount=%u", - &h, h.size(), h.capacity(), h.bucketCount()); - for (size_t i = 0; i < h.bucketCount(); i++) { - bool collision, present; - hash_t hash; - BasicHashtableTest::cookieAt(h, i, &collision, &present, &hash); - if (present) { - int key, value; - getKeyValue(h.entryAt(i), &key, &value); - ALOGD(" [%3u] = collision=%d, present=%d, hash=0x%08x, key=%3d, value=%3d, " - "hash_type(key)=0x%08x", - i, collision, present, hash, key, value, hash_type(key)); - } else { - ALOGD(" [%3u] = collision=%d, present=%d", - i, collision, present); - } - } -} - -TEST_F(BasicHashtableTest, DefaultConstructor_WithDefaultProperties) { - SimpleHashtable h; - - EXPECT_EQ(0U, h.size()); - EXPECT_EQ(3U, h.capacity()); - EXPECT_EQ(5U, h.bucketCount()); - EXPECT_EQ(0.75f, h.loadFactor()); -} - -TEST_F(BasicHashtableTest, Constructor_WithNonUnityLoadFactor) { - SimpleHashtable h(52, 0.8f); - - EXPECT_EQ(0U, h.size()); - EXPECT_EQ(77U, h.capacity()); - EXPECT_EQ(97U, h.bucketCount()); - EXPECT_EQ(0.8f, h.loadFactor()); -} - -TEST_F(BasicHashtableTest, Constructor_WithUnityLoadFactorAndExactCapacity) { - SimpleHashtable h(46, 1.0f); - - EXPECT_EQ(0U, h.size()); - EXPECT_EQ(46U, h.capacity()); // must be one less than bucketCount because loadFactor == 1.0f - EXPECT_EQ(47U, h.bucketCount()); - EXPECT_EQ(1.0f, h.loadFactor()); -} - -TEST_F(BasicHashtableTest, Constructor_WithUnityLoadFactorAndInexactCapacity) { - SimpleHashtable h(42, 1.0f); - - EXPECT_EQ(0U, h.size()); - EXPECT_EQ(46U, h.capacity()); // must be one less than bucketCount because loadFactor == 1.0f - EXPECT_EQ(47U, h.bucketCount()); - EXPECT_EQ(1.0f, h.loadFactor()); -} - -TEST_F(BasicHashtableTest, FindAddFindRemoveFind_OneEntry) { - SimpleHashtable h; - ssize_t index = find(h, -1, 8); - ASSERT_EQ(-1, index); - - index = add(h, 8, 1); - ASSERT_EQ(1U, h.size()); - - ASSERT_EQ(index, find(h, -1, 8)); - ASSERT_EQ(8, h.entryAt(index).key); - ASSERT_EQ(1, h.entryAt(index).value); - - index = find(h, index, 8); - ASSERT_EQ(-1, index); - - ASSERT_TRUE(remove(h, 8)); - ASSERT_EQ(0U, h.size()); - - index = find(h, -1, 8); - ASSERT_EQ(-1, index); -} - -TEST_F(BasicHashtableTest, FindAddFindRemoveFind_MultipleEntryWithUniqueKey) { - const size_t N = 11; - - SimpleHashtable h; - for (size_t i = 0; i < N; i++) { - ssize_t index = find(h, -1, int(i)); - ASSERT_EQ(-1, index); - - index = add(h, int(i), int(i * 10)); - ASSERT_EQ(i + 1, h.size()); - - ASSERT_EQ(index, find(h, -1, int(i))); - ASSERT_EQ(int(i), h.entryAt(index).key); - ASSERT_EQ(int(i * 10), h.entryAt(index).value); - - index = find(h, index, int(i)); - ASSERT_EQ(-1, index); - } - - for (size_t i = N; --i > 0; ) { - ASSERT_TRUE(remove(h, int(i))) << "i = " << i; - ASSERT_EQ(i, h.size()); - - ssize_t index = find(h, -1, int(i)); - ASSERT_EQ(-1, index); - } -} - -TEST_F(BasicHashtableTest, FindAddFindRemoveFind_MultipleEntryWithDuplicateKey) { - const size_t N = 11; - const int K = 1; - - SimpleHashtable h; - for (size_t i = 0; i < N; i++) { - ssize_t index = find(h, -1, K); - if (i == 0) { - ASSERT_EQ(-1, index); - } else { - ASSERT_NE(-1, index); - } - - add(h, K, int(i)); - ASSERT_EQ(i + 1, h.size()); - - index = -1; - int values = 0; - for (size_t j = 0; j <= i; j++) { - index = find(h, index, K); - ASSERT_GE(index, 0); - ASSERT_EQ(K, h.entryAt(index).key); - values |= 1 << h.entryAt(index).value; - } - ASSERT_EQ(values, (1 << (i + 1)) - 1); - - index = find(h, index, K); - ASSERT_EQ(-1, index); - } - - for (size_t i = N; --i > 0; ) { - ASSERT_TRUE(remove(h, K)) << "i = " << i; - ASSERT_EQ(i, h.size()); - - ssize_t index = -1; - for (size_t j = 0; j < i; j++) { - index = find(h, index, K); - ASSERT_GE(index, 0); - ASSERT_EQ(K, h.entryAt(index).key); - } - - index = find(h, index, K); - ASSERT_EQ(-1, index); - } -} - -TEST_F(BasicHashtableTest, Clear_WhenAlreadyEmpty_DoesNothing) { - SimpleHashtable h; - h.clear(); - - EXPECT_EQ(0U, h.size()); - EXPECT_EQ(3U, h.capacity()); - EXPECT_EQ(5U, h.bucketCount()); - EXPECT_EQ(0.75f, h.loadFactor()); -} - -TEST_F(BasicHashtableTest, Clear_AfterElementsAdded_RemovesThem) { - SimpleHashtable h; - add(h, 0, 0); - add(h, 1, 0); - h.clear(); - - EXPECT_EQ(0U, h.size()); - EXPECT_EQ(3U, h.capacity()); - EXPECT_EQ(5U, h.bucketCount()); - EXPECT_EQ(0.75f, h.loadFactor()); -} - -TEST_F(BasicHashtableTest, Clear_AfterElementsAdded_DestroysThem) { - ComplexHashtable h; - add(h, ComplexKey(0), ComplexValue(0)); - add(h, ComplexKey(1), ComplexValue(0)); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); - - h.clear(); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); - - EXPECT_EQ(0U, h.size()); - EXPECT_EQ(3U, h.capacity()); - EXPECT_EQ(5U, h.bucketCount()); - EXPECT_EQ(0.75f, h.loadFactor()); -} - -TEST_F(BasicHashtableTest, Remove_AfterElementsAdded_DestroysThem) { - ComplexHashtable h; - add(h, ComplexKey(0), ComplexValue(0)); - add(h, ComplexKey(1), ComplexValue(0)); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); - - ASSERT_TRUE(remove(h, ComplexKey(0))); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1)); - - ASSERT_TRUE(remove(h, ComplexKey(1))); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); - - EXPECT_EQ(0U, h.size()); - EXPECT_EQ(3U, h.capacity()); - EXPECT_EQ(5U, h.bucketCount()); - EXPECT_EQ(0.75f, h.loadFactor()); -} - -TEST_F(BasicHashtableTest, Destructor_AfterElementsAdded_DestroysThem) { - { - ComplexHashtable h; - add(h, ComplexKey(0), ComplexValue(0)); - add(h, ComplexKey(1), ComplexValue(0)); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); - } // h is destroyed here - - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); -} - -TEST_F(BasicHashtableTest, Next_WhenEmpty_ReturnsMinusOne) { - SimpleHashtable h; - - ASSERT_EQ(-1, h.next(-1)); -} - -TEST_F(BasicHashtableTest, Next_WhenNonEmpty_IteratesOverAllEntries) { - const int N = 88; - - SimpleHashtable h; - for (int i = 0; i < N; i++) { - add(h, i, i * 10); - } - - bool set[N]; - memset(set, 0, sizeof(bool) * N); - int count = 0; - for (ssize_t index = -1; (index = h.next(index)) != -1; ) { - ASSERT_GE(index, 0); - ASSERT_LT(size_t(index), h.bucketCount()); - - const SimpleEntry& entry = h.entryAt(index); - ASSERT_GE(entry.key, 0); - ASSERT_LT(entry.key, N); - ASSERT_EQ(false, set[entry.key]); - ASSERT_EQ(entry.key * 10, entry.value); - - set[entry.key] = true; - count += 1; - } - ASSERT_EQ(N, count); -} - -TEST_F(BasicHashtableTest, Add_RehashesOnDemand) { - SimpleHashtable h; - size_t initialCapacity = h.capacity(); - size_t initialBucketCount = h.bucketCount(); - - for (size_t i = 0; i < initialCapacity; i++) { - add(h, int(i), 0); - } - - EXPECT_EQ(initialCapacity, h.size()); - EXPECT_EQ(initialCapacity, h.capacity()); - EXPECT_EQ(initialBucketCount, h.bucketCount()); - - add(h, -1, -1); - - EXPECT_EQ(initialCapacity + 1, h.size()); - EXPECT_GT(h.capacity(), initialCapacity); - EXPECT_GT(h.bucketCount(), initialBucketCount); - EXPECT_GT(h.bucketCount(), h.capacity()); -} - -TEST_F(BasicHashtableTest, Rehash_WhenCapacityAndBucketCountUnchanged_DoesNothing) { - ComplexHashtable h; - add(h, ComplexKey(0), ComplexValue(0)); - const void* oldBuckets = getBuckets(h); - ASSERT_NE((void*)NULL, oldBuckets); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1)); - - h.rehash(h.capacity(), h.loadFactor()); - - ASSERT_EQ(oldBuckets, getBuckets(h)); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1)); -} - -TEST_F(BasicHashtableTest, Rehash_WhenEmptyAndHasNoBuckets_ButDoesNotAllocateBuckets) { - ComplexHashtable h; - ASSERT_EQ((void*)NULL, getBuckets(h)); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); - - h.rehash(9, 1.0f); - - EXPECT_EQ(0U, h.size()); - EXPECT_EQ(10U, h.capacity()); - EXPECT_EQ(11U, h.bucketCount()); - EXPECT_EQ(1.0f, h.loadFactor()); - EXPECT_EQ((void*)NULL, getBuckets(h)); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); -} - -TEST_F(BasicHashtableTest, Rehash_WhenEmptyAndHasBuckets_ReleasesBucketsAndSetsCapacity) { - ComplexHashtable h(10); - add(h, ComplexKey(0), ComplexValue(0)); - ASSERT_TRUE(remove(h, ComplexKey(0))); - ASSERT_NE((void*)NULL, getBuckets(h)); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); - - h.rehash(0, 0.75f); - - EXPECT_EQ(0U, h.size()); - EXPECT_EQ(3U, h.capacity()); - EXPECT_EQ(5U, h.bucketCount()); - EXPECT_EQ(0.75f, h.loadFactor()); - EXPECT_EQ((void*)NULL, getBuckets(h)); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); -} - -TEST_F(BasicHashtableTest, Rehash_WhenLessThanCurrentCapacity_ShrinksBuckets) { - ComplexHashtable h(10); - add(h, ComplexKey(0), ComplexValue(0)); - add(h, ComplexKey(1), ComplexValue(1)); - const void* oldBuckets = getBuckets(h); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); - - h.rehash(0, 0.75f); - - EXPECT_EQ(2U, h.size()); - EXPECT_EQ(3U, h.capacity()); - EXPECT_EQ(5U, h.bucketCount()); - EXPECT_EQ(0.75f, h.loadFactor()); - EXPECT_NE(oldBuckets, getBuckets(h)); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); -} - -TEST_F(BasicHashtableTest, CopyOnWrite) { - ComplexHashtable h1; - add(h1, ComplexKey(0), ComplexValue(0)); - add(h1, ComplexKey(1), ComplexValue(1)); - const void* originalBuckets = getBuckets(h1); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); - ssize_t index0 = find(h1, -1, ComplexKey(0)); - EXPECT_GE(index0, 0); - - // copy constructor acquires shared reference - ComplexHashtable h2(h1); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); - ASSERT_EQ(originalBuckets, getBuckets(h2)); - EXPECT_EQ(h1.size(), h2.size()); - EXPECT_EQ(h1.capacity(), h2.capacity()); - EXPECT_EQ(h1.bucketCount(), h2.bucketCount()); - EXPECT_EQ(h1.loadFactor(), h2.loadFactor()); - EXPECT_EQ(index0, find(h2, -1, ComplexKey(0))); - - // operator= acquires shared reference - ComplexHashtable h3; - h3 = h2; - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); - ASSERT_EQ(originalBuckets, getBuckets(h3)); - EXPECT_EQ(h1.size(), h3.size()); - EXPECT_EQ(h1.capacity(), h3.capacity()); - EXPECT_EQ(h1.bucketCount(), h3.bucketCount()); - EXPECT_EQ(h1.loadFactor(), h3.loadFactor()); - EXPECT_EQ(index0, find(h3, -1, ComplexKey(0))); - - // editEntryAt copies shared contents - h1.editEntryAt(index0).value.v = 42; - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4)); - ASSERT_NE(originalBuckets, getBuckets(h1)); - EXPECT_EQ(42, h1.entryAt(index0).value.v); - EXPECT_EQ(0, h2.entryAt(index0).value.v); - EXPECT_EQ(0, h3.entryAt(index0).value.v); - - // clear releases reference to shared contents - h2.clear(); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4)); - EXPECT_EQ(0U, h2.size()); - ASSERT_NE(originalBuckets, getBuckets(h2)); - - // operator= acquires shared reference, destroys unshared contents - h1 = h3; - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); - ASSERT_EQ(originalBuckets, getBuckets(h1)); - EXPECT_EQ(h3.size(), h1.size()); - EXPECT_EQ(h3.capacity(), h1.capacity()); - EXPECT_EQ(h3.bucketCount(), h1.bucketCount()); - EXPECT_EQ(h3.loadFactor(), h1.loadFactor()); - EXPECT_EQ(index0, find(h1, -1, ComplexKey(0))); - - // add copies shared contents - add(h1, ComplexKey(2), ComplexValue(2)); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(5, 5)); - ASSERT_NE(originalBuckets, getBuckets(h1)); - EXPECT_EQ(3U, h1.size()); - EXPECT_EQ(0U, h2.size()); - EXPECT_EQ(2U, h3.size()); - - // remove copies shared contents - h1 = h3; - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); - ASSERT_EQ(originalBuckets, getBuckets(h1)); - h1.removeAt(index0); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(3, 3)); - ASSERT_NE(originalBuckets, getBuckets(h1)); - EXPECT_EQ(1U, h1.size()); - EXPECT_EQ(0U, h2.size()); - EXPECT_EQ(2U, h3.size()); - - // rehash copies shared contents - h1 = h3; - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); - ASSERT_EQ(originalBuckets, getBuckets(h1)); - h1.rehash(10, 1.0f); - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4)); - ASSERT_NE(originalBuckets, getBuckets(h1)); - EXPECT_EQ(2U, h1.size()); - EXPECT_EQ(0U, h2.size()); - EXPECT_EQ(2U, h3.size()); -} - -} // namespace android diff --git a/libs/utils/tests/BitSet_test.cpp b/libs/utils/tests/BitSet_test.cpp deleted file mode 100644 index 752e56d..0000000 --- a/libs/utils/tests/BitSet_test.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2013 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 "BitSet_test" - -#include <utils/BitSet.h> -#include <cutils/log.h> -#include <gtest/gtest.h> -#include <unistd.h> - -namespace android { - -class BitSetTest : public testing::Test { -protected: - BitSet32 b1; - BitSet32 b2; - virtual void TearDown() { - b1.clear(); - b2.clear(); - } -}; - - -TEST_F(BitSetTest, BitWiseOr) { - b1.markBit(2); - b2.markBit(4); - - BitSet32 tmp = b1 | b2; - EXPECT_EQ(tmp.count(), 2u); - EXPECT_TRUE(tmp.hasBit(2) && tmp.hasBit(4)); - // Check that the operator is symmetric - EXPECT_TRUE((b2 | b1) == (b1 | b2)); - - b1 |= b2; - EXPECT_EQ(b1.count(), 2u); - EXPECT_TRUE(b1.hasBit(2) && b1.hasBit(4)); - EXPECT_TRUE(b2.hasBit(4) && b2.count() == 1u); -} -TEST_F(BitSetTest, BitWiseAnd_Disjoint) { - b1.markBit(2); - b1.markBit(4); - b1.markBit(6); - - BitSet32 tmp = b1 & b2; - EXPECT_TRUE(tmp.isEmpty()); - // Check that the operator is symmetric - EXPECT_TRUE((b2 & b1) == (b1 & b2)); - - b2 &= b1; - EXPECT_TRUE(b2.isEmpty()); - EXPECT_EQ(b1.count(), 3u); - EXPECT_TRUE(b1.hasBit(2) && b1.hasBit(4) && b1.hasBit(6)); -} - -TEST_F(BitSetTest, BitWiseAnd_NonDisjoint) { - b1.markBit(2); - b1.markBit(4); - b1.markBit(6); - b2.markBit(3); - b2.markBit(6); - b2.markBit(9); - - BitSet32 tmp = b1 & b2; - EXPECT_EQ(tmp.count(), 1u); - EXPECT_TRUE(tmp.hasBit(6)); - // Check that the operator is symmetric - EXPECT_TRUE((b2 & b1) == (b1 & b2)); - - b1 &= b2; - EXPECT_EQ(b1.count(), 1u); - EXPECT_EQ(b2.count(), 3u); - EXPECT_TRUE(b2.hasBit(3) && b2.hasBit(6) && b2.hasBit(9)); -} -} // namespace android diff --git a/libs/utils/tests/BlobCache_test.cpp b/libs/utils/tests/BlobCache_test.cpp deleted file mode 100644 index 7202123..0000000 --- a/libs/utils/tests/BlobCache_test.cpp +++ /dev/null @@ -1,421 +0,0 @@ -/* - ** Copyright 2011, 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. - */ - -#include <fcntl.h> -#include <stdio.h> - -#include <gtest/gtest.h> - -#include <utils/BlobCache.h> -#include <utils/Errors.h> - -namespace android { - -class BlobCacheTest : public ::testing::Test { -protected: - enum { - MAX_KEY_SIZE = 6, - MAX_VALUE_SIZE = 8, - MAX_TOTAL_SIZE = 13, - }; - - virtual void SetUp() { - mBC = new BlobCache(MAX_KEY_SIZE, MAX_VALUE_SIZE, MAX_TOTAL_SIZE); - } - - virtual void TearDown() { - mBC.clear(); - } - - sp<BlobCache> mBC; -}; - -TEST_F(BlobCacheTest, CacheSingleValueSucceeds) { - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; - mBC->set("abcd", 4, "efgh", 4); - ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4)); - ASSERT_EQ('e', buf[0]); - ASSERT_EQ('f', buf[1]); - ASSERT_EQ('g', buf[2]); - ASSERT_EQ('h', buf[3]); -} - -TEST_F(BlobCacheTest, CacheTwoValuesSucceeds) { - char buf[2] = { 0xee, 0xee }; - mBC->set("ab", 2, "cd", 2); - mBC->set("ef", 2, "gh", 2); - ASSERT_EQ(size_t(2), mBC->get("ab", 2, buf, 2)); - ASSERT_EQ('c', buf[0]); - ASSERT_EQ('d', buf[1]); - ASSERT_EQ(size_t(2), mBC->get("ef", 2, buf, 2)); - ASSERT_EQ('g', buf[0]); - ASSERT_EQ('h', buf[1]); -} - -TEST_F(BlobCacheTest, GetOnlyWritesInsideBounds) { - char buf[6] = { 0xee, 0xee, 0xee, 0xee, 0xee, 0xee }; - mBC->set("abcd", 4, "efgh", 4); - ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf+1, 4)); - ASSERT_EQ(0xee, buf[0]); - ASSERT_EQ('e', buf[1]); - ASSERT_EQ('f', buf[2]); - ASSERT_EQ('g', buf[3]); - ASSERT_EQ('h', buf[4]); - ASSERT_EQ(0xee, buf[5]); -} - -TEST_F(BlobCacheTest, GetOnlyWritesIfBufferIsLargeEnough) { - char buf[3] = { 0xee, 0xee, 0xee }; - mBC->set("abcd", 4, "efgh", 4); - ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 3)); - ASSERT_EQ(0xee, buf[0]); - ASSERT_EQ(0xee, buf[1]); - ASSERT_EQ(0xee, buf[2]); -} - -TEST_F(BlobCacheTest, GetDoesntAccessNullBuffer) { - mBC->set("abcd", 4, "efgh", 4); - ASSERT_EQ(size_t(4), mBC->get("abcd", 4, NULL, 0)); -} - -TEST_F(BlobCacheTest, MultipleSetsCacheLatestValue) { - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; - mBC->set("abcd", 4, "efgh", 4); - mBC->set("abcd", 4, "ijkl", 4); - ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4)); - ASSERT_EQ('i', buf[0]); - ASSERT_EQ('j', buf[1]); - ASSERT_EQ('k', buf[2]); - ASSERT_EQ('l', buf[3]); -} - -TEST_F(BlobCacheTest, SecondSetKeepsFirstValueIfTooLarge) { - char buf[MAX_VALUE_SIZE+1] = { 0xee, 0xee, 0xee, 0xee }; - mBC->set("abcd", 4, "efgh", 4); - mBC->set("abcd", 4, buf, MAX_VALUE_SIZE+1); - ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4)); - ASSERT_EQ('e', buf[0]); - ASSERT_EQ('f', buf[1]); - ASSERT_EQ('g', buf[2]); - ASSERT_EQ('h', buf[3]); -} - -TEST_F(BlobCacheTest, DoesntCacheIfKeyIsTooBig) { - char key[MAX_KEY_SIZE+1]; - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; - for (int i = 0; i < MAX_KEY_SIZE+1; i++) { - key[i] = 'a'; - } - mBC->set(key, MAX_KEY_SIZE+1, "bbbb", 4); - ASSERT_EQ(size_t(0), mBC->get(key, MAX_KEY_SIZE+1, buf, 4)); - ASSERT_EQ(0xee, buf[0]); - ASSERT_EQ(0xee, buf[1]); - ASSERT_EQ(0xee, buf[2]); - ASSERT_EQ(0xee, buf[3]); -} - -TEST_F(BlobCacheTest, DoesntCacheIfValueIsTooBig) { - char buf[MAX_VALUE_SIZE+1]; - for (int i = 0; i < MAX_VALUE_SIZE+1; i++) { - buf[i] = 'b'; - } - mBC->set("abcd", 4, buf, MAX_VALUE_SIZE+1); - for (int i = 0; i < MAX_VALUE_SIZE+1; i++) { - buf[i] = 0xee; - } - ASSERT_EQ(size_t(0), mBC->get("abcd", 4, buf, MAX_VALUE_SIZE+1)); - for (int i = 0; i < MAX_VALUE_SIZE+1; i++) { - SCOPED_TRACE(i); - ASSERT_EQ(0xee, buf[i]); - } -} - -TEST_F(BlobCacheTest, DoesntCacheIfKeyValuePairIsTooBig) { - // Check a testing assumptions - ASSERT_TRUE(MAX_TOTAL_SIZE < MAX_KEY_SIZE + MAX_VALUE_SIZE); - ASSERT_TRUE(MAX_KEY_SIZE < MAX_TOTAL_SIZE); - - enum { bufSize = MAX_TOTAL_SIZE - MAX_KEY_SIZE + 1 }; - - char key[MAX_KEY_SIZE]; - char buf[bufSize]; - for (int i = 0; i < MAX_KEY_SIZE; i++) { - key[i] = 'a'; - } - for (int i = 0; i < bufSize; i++) { - buf[i] = 'b'; - } - - mBC->set(key, MAX_KEY_SIZE, buf, MAX_VALUE_SIZE); - ASSERT_EQ(size_t(0), mBC->get(key, MAX_KEY_SIZE, NULL, 0)); -} - -TEST_F(BlobCacheTest, CacheMaxKeySizeSucceeds) { - char key[MAX_KEY_SIZE]; - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; - for (int i = 0; i < MAX_KEY_SIZE; i++) { - key[i] = 'a'; - } - mBC->set(key, MAX_KEY_SIZE, "wxyz", 4); - ASSERT_EQ(size_t(4), mBC->get(key, MAX_KEY_SIZE, buf, 4)); - ASSERT_EQ('w', buf[0]); - ASSERT_EQ('x', buf[1]); - ASSERT_EQ('y', buf[2]); - ASSERT_EQ('z', buf[3]); -} - -TEST_F(BlobCacheTest, CacheMaxValueSizeSucceeds) { - char buf[MAX_VALUE_SIZE]; - for (int i = 0; i < MAX_VALUE_SIZE; i++) { - buf[i] = 'b'; - } - mBC->set("abcd", 4, buf, MAX_VALUE_SIZE); - for (int i = 0; i < MAX_VALUE_SIZE; i++) { - buf[i] = 0xee; - } - ASSERT_EQ(size_t(MAX_VALUE_SIZE), mBC->get("abcd", 4, buf, - MAX_VALUE_SIZE)); - for (int i = 0; i < MAX_VALUE_SIZE; i++) { - SCOPED_TRACE(i); - ASSERT_EQ('b', buf[i]); - } -} - -TEST_F(BlobCacheTest, CacheMaxKeyValuePairSizeSucceeds) { - // Check a testing assumption - ASSERT_TRUE(MAX_KEY_SIZE < MAX_TOTAL_SIZE); - - enum { bufSize = MAX_TOTAL_SIZE - MAX_KEY_SIZE }; - - char key[MAX_KEY_SIZE]; - char buf[bufSize]; - for (int i = 0; i < MAX_KEY_SIZE; i++) { - key[i] = 'a'; - } - for (int i = 0; i < bufSize; i++) { - buf[i] = 'b'; - } - - mBC->set(key, MAX_KEY_SIZE, buf, bufSize); - ASSERT_EQ(size_t(bufSize), mBC->get(key, MAX_KEY_SIZE, NULL, 0)); -} - -TEST_F(BlobCacheTest, CacheMinKeyAndValueSizeSucceeds) { - char buf[1] = { 0xee }; - mBC->set("x", 1, "y", 1); - ASSERT_EQ(size_t(1), mBC->get("x", 1, buf, 1)); - ASSERT_EQ('y', buf[0]); -} - -TEST_F(BlobCacheTest, CacheSizeDoesntExceedTotalLimit) { - for (int i = 0; i < 256; i++) { - uint8_t k = i; - mBC->set(&k, 1, "x", 1); - } - int numCached = 0; - for (int i = 0; i < 256; i++) { - uint8_t k = i; - if (mBC->get(&k, 1, NULL, 0) == 1) { - numCached++; - } - } - ASSERT_GE(MAX_TOTAL_SIZE / 2, numCached); -} - -TEST_F(BlobCacheTest, ExceedingTotalLimitHalvesCacheSize) { - // Fill up the entire cache with 1 char key/value pairs. - const int maxEntries = MAX_TOTAL_SIZE / 2; - for (int i = 0; i < maxEntries; i++) { - uint8_t k = i; - mBC->set(&k, 1, "x", 1); - } - // Insert one more entry, causing a cache overflow. - { - uint8_t k = maxEntries; - mBC->set(&k, 1, "x", 1); - } - // Count the number of entries in the cache. - int numCached = 0; - for (int i = 0; i < maxEntries+1; i++) { - uint8_t k = i; - if (mBC->get(&k, 1, NULL, 0) == 1) { - numCached++; - } - } - ASSERT_EQ(maxEntries/2 + 1, numCached); -} - -class BlobCacheFlattenTest : public BlobCacheTest { -protected: - virtual void SetUp() { - BlobCacheTest::SetUp(); - mBC2 = new BlobCache(MAX_KEY_SIZE, MAX_VALUE_SIZE, MAX_TOTAL_SIZE); - } - - virtual void TearDown() { - mBC2.clear(); - BlobCacheTest::TearDown(); - } - - void roundTrip() { - size_t size = mBC->getFlattenedSize(); - uint8_t* flat = new uint8_t[size]; - ASSERT_EQ(OK, mBC->flatten(flat, size)); - ASSERT_EQ(OK, mBC2->unflatten(flat, size)); - delete[] flat; - } - - sp<BlobCache> mBC2; -}; - -TEST_F(BlobCacheFlattenTest, FlattenOneValue) { - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; - mBC->set("abcd", 4, "efgh", 4); - roundTrip(); - ASSERT_EQ(size_t(4), mBC2->get("abcd", 4, buf, 4)); - ASSERT_EQ('e', buf[0]); - ASSERT_EQ('f', buf[1]); - ASSERT_EQ('g', buf[2]); - ASSERT_EQ('h', buf[3]); -} - -TEST_F(BlobCacheFlattenTest, FlattenFullCache) { - // Fill up the entire cache with 1 char key/value pairs. - const int maxEntries = MAX_TOTAL_SIZE / 2; - for (int i = 0; i < maxEntries; i++) { - uint8_t k = i; - mBC->set(&k, 1, &k, 1); - } - - roundTrip(); - - // Verify the deserialized cache - for (int i = 0; i < maxEntries; i++) { - uint8_t k = i; - uint8_t v = 0xee; - ASSERT_EQ(size_t(1), mBC2->get(&k, 1, &v, 1)); - ASSERT_EQ(k, v); - } -} - -TEST_F(BlobCacheFlattenTest, FlattenDoesntChangeCache) { - // Fill up the entire cache with 1 char key/value pairs. - const int maxEntries = MAX_TOTAL_SIZE / 2; - for (int i = 0; i < maxEntries; i++) { - uint8_t k = i; - mBC->set(&k, 1, &k, 1); - } - - size_t size = mBC->getFlattenedSize(); - uint8_t* flat = new uint8_t[size]; - ASSERT_EQ(OK, mBC->flatten(flat, size)); - delete[] flat; - - // Verify the cache that we just serialized - for (int i = 0; i < maxEntries; i++) { - uint8_t k = i; - uint8_t v = 0xee; - ASSERT_EQ(size_t(1), mBC->get(&k, 1, &v, 1)); - ASSERT_EQ(k, v); - } -} - -TEST_F(BlobCacheFlattenTest, FlattenCatchesBufferTooSmall) { - // Fill up the entire cache with 1 char key/value pairs. - const int maxEntries = MAX_TOTAL_SIZE / 2; - for (int i = 0; i < maxEntries; i++) { - uint8_t k = i; - mBC->set(&k, 1, &k, 1); - } - - size_t size = mBC->getFlattenedSize() - 1; - uint8_t* flat = new uint8_t[size]; - ASSERT_EQ(BAD_VALUE, mBC->flatten(flat, size)); - delete[] flat; -} - -TEST_F(BlobCacheFlattenTest, UnflattenCatchesBadMagic) { - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; - mBC->set("abcd", 4, "efgh", 4); - - size_t size = mBC->getFlattenedSize(); - uint8_t* flat = new uint8_t[size]; - ASSERT_EQ(OK, mBC->flatten(flat, size)); - flat[1] = ~flat[1]; - - // Bad magic should cause an error. - ASSERT_EQ(BAD_VALUE, mBC2->unflatten(flat, size)); - delete[] flat; - - // The error should cause the unflatten to result in an empty cache - ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4)); -} - -TEST_F(BlobCacheFlattenTest, UnflattenCatchesBadBlobCacheVersion) { - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; - mBC->set("abcd", 4, "efgh", 4); - - size_t size = mBC->getFlattenedSize(); - uint8_t* flat = new uint8_t[size]; - ASSERT_EQ(OK, mBC->flatten(flat, size)); - flat[5] = ~flat[5]; - - // Version mismatches shouldn't cause errors, but should not use the - // serialized entries - ASSERT_EQ(OK, mBC2->unflatten(flat, size)); - delete[] flat; - - // The version mismatch should cause the unflatten to result in an empty - // cache - ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4)); -} - -TEST_F(BlobCacheFlattenTest, UnflattenCatchesBadBlobCacheDeviceVersion) { - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; - mBC->set("abcd", 4, "efgh", 4); - - size_t size = mBC->getFlattenedSize(); - uint8_t* flat = new uint8_t[size]; - ASSERT_EQ(OK, mBC->flatten(flat, size)); - flat[10] = ~flat[10]; - - // Version mismatches shouldn't cause errors, but should not use the - // serialized entries - ASSERT_EQ(OK, mBC2->unflatten(flat, size)); - delete[] flat; - - // The version mismatch should cause the unflatten to result in an empty - // cache - ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4)); -} - -TEST_F(BlobCacheFlattenTest, UnflattenCatchesBufferTooSmall) { - char buf[4] = { 0xee, 0xee, 0xee, 0xee }; - mBC->set("abcd", 4, "efgh", 4); - - size_t size = mBC->getFlattenedSize(); - uint8_t* flat = new uint8_t[size]; - ASSERT_EQ(OK, mBC->flatten(flat, size)); - - // A buffer truncation shouldt cause an error - ASSERT_EQ(BAD_VALUE, mBC2->unflatten(flat, size-1)); - delete[] flat; - - // The error should cause the unflatten to result in an empty cache - ASSERT_EQ(size_t(0), mBC2->get("abcd", 4, buf, 4)); -} - -} // namespace android diff --git a/libs/utils/tests/Looper_test.cpp b/libs/utils/tests/Looper_test.cpp deleted file mode 100644 index 8bf2ba2..0000000 --- a/libs/utils/tests/Looper_test.cpp +++ /dev/null @@ -1,693 +0,0 @@ -// -// Copyright 2010 The Android Open Source Project -// - -#include <utils/Looper.h> -#include <utils/Timers.h> -#include <utils/StopWatch.h> -#include <gtest/gtest.h> -#include <unistd.h> -#include <time.h> - -#include "TestHelpers.h" - -// # of milliseconds to fudge stopwatch measurements -#define TIMING_TOLERANCE_MS 25 - -namespace android { - -enum { - MSG_TEST1 = 1, - MSG_TEST2 = 2, - MSG_TEST3 = 3, - MSG_TEST4 = 4, -}; - -class DelayedWake : public DelayedTask { - sp<Looper> mLooper; - -public: - DelayedWake(int delayMillis, const sp<Looper> looper) : - DelayedTask(delayMillis), mLooper(looper) { - } - -protected: - virtual void doTask() { - mLooper->wake(); - } -}; - -class DelayedWriteSignal : public DelayedTask { - Pipe* mPipe; - -public: - DelayedWriteSignal(int delayMillis, Pipe* pipe) : - DelayedTask(delayMillis), mPipe(pipe) { - } - -protected: - virtual void doTask() { - mPipe->writeSignal(); - } -}; - -class CallbackHandler { -public: - void setCallback(const sp<Looper>& looper, int fd, int events) { - looper->addFd(fd, 0, events, staticHandler, this); - } - -protected: - virtual ~CallbackHandler() { } - - virtual int handler(int fd, int events) = 0; - -private: - static int staticHandler(int fd, int events, void* data) { - return static_cast<CallbackHandler*>(data)->handler(fd, events); - } -}; - -class StubCallbackHandler : public CallbackHandler { -public: - int nextResult; - int callbackCount; - - int fd; - int events; - - StubCallbackHandler(int nextResult) : nextResult(nextResult), - callbackCount(0), fd(-1), events(-1) { - } - -protected: - virtual int handler(int fd, int events) { - callbackCount += 1; - this->fd = fd; - this->events = events; - return nextResult; - } -}; - -class StubMessageHandler : public MessageHandler { -public: - Vector<Message> messages; - - virtual void handleMessage(const Message& message) { - messages.push(message); - } -}; - -class LooperTest : public testing::Test { -protected: - sp<Looper> mLooper; - - virtual void SetUp() { - mLooper = new Looper(true); - } - - virtual void TearDown() { - mLooper.clear(); - } -}; - - -TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNotAwoken_WaitsForTimeout) { - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(100); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. equal timeout"; - EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result) - << "pollOnce result should be ALOOPER_POLL_TIMEOUT"; -} - -TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenBeforeWaiting_ImmediatelyReturns) { - mLooper->wake(); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(1000); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. zero because wake() was called before waiting"; - EXPECT_EQ(ALOOPER_POLL_WAKE, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because loop was awoken"; -} - -TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenWhileWaiting_PromptlyReturns) { - sp<DelayedWake> delayedWake = new DelayedWake(100, mLooper); - delayedWake->run(); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(1000); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. equal wake delay"; - EXPECT_EQ(ALOOPER_POLL_WAKE, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because loop was awoken"; -} - -TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoRegisteredFDs_ImmediatelyReturns) { - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(0); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should be approx. zero"; - EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result) - << "pollOnce result should be ALOOPER_POLL_TIMEOUT"; -} - -TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoSignalledFDs_ImmediatelyReturns) { - Pipe pipe; - StubCallbackHandler handler(true); - - handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(0); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should be approx. zero"; - EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result) - << "pollOnce result should be ALOOPER_POLL_TIMEOUT"; - EXPECT_EQ(0, handler.callbackCount) - << "callback should not have been invoked because FD was not signalled"; -} - -TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndSignalledFD_ImmediatelyInvokesCallbackAndReturns) { - Pipe pipe; - StubCallbackHandler handler(true); - - ASSERT_EQ(OK, pipe.writeSignal()); - handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(0); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should be approx. zero"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled"; - EXPECT_EQ(1, handler.callbackCount) - << "callback should be invoked exactly once"; - EXPECT_EQ(pipe.receiveFd, handler.fd) - << "callback should have received pipe fd as parameter"; - EXPECT_EQ(ALOOPER_EVENT_INPUT, handler.events) - << "callback should have received ALOOPER_EVENT_INPUT as events"; -} - -TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNoSignalledFDs_WaitsForTimeoutAndReturns) { - Pipe pipe; - StubCallbackHandler handler(true); - - handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(100); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. equal timeout"; - EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result) - << "pollOnce result should be ALOOPER_POLL_TIMEOUT"; - EXPECT_EQ(0, handler.callbackCount) - << "callback should not have been invoked because FD was not signalled"; -} - -TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDBeforeWaiting_ImmediatelyInvokesCallbackAndReturns) { - Pipe pipe; - StubCallbackHandler handler(true); - - pipe.writeSignal(); - handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(100); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - ASSERT_EQ(OK, pipe.readSignal()) - << "signal should actually have been written"; - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should be approx. zero"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled"; - EXPECT_EQ(1, handler.callbackCount) - << "callback should be invoked exactly once"; - EXPECT_EQ(pipe.receiveFd, handler.fd) - << "callback should have received pipe fd as parameter"; - EXPECT_EQ(ALOOPER_EVENT_INPUT, handler.events) - << "callback should have received ALOOPER_EVENT_INPUT as events"; -} - -TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDWhileWaiting_PromptlyInvokesCallbackAndReturns) { - Pipe pipe; - StubCallbackHandler handler(true); - sp<DelayedWriteSignal> delayedWriteSignal = new DelayedWriteSignal(100, & pipe); - - handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); - delayedWriteSignal->run(); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(1000); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - ASSERT_EQ(OK, pipe.readSignal()) - << "signal should actually have been written"; - EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. equal signal delay"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled"; - EXPECT_EQ(1, handler.callbackCount) - << "callback should be invoked exactly once"; - EXPECT_EQ(pipe.receiveFd, handler.fd) - << "callback should have received pipe fd as parameter"; - EXPECT_EQ(ALOOPER_EVENT_INPUT, handler.events) - << "callback should have received ALOOPER_EVENT_INPUT as events"; -} - -TEST_F(LooperTest, PollOnce_WhenCallbackAddedThenRemoved_CallbackShouldNotBeInvoked) { - Pipe pipe; - StubCallbackHandler handler(true); - - handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); - pipe.writeSignal(); // would cause FD to be considered signalled - mLooper->removeFd(pipe.receiveFd); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(100); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - ASSERT_EQ(OK, pipe.readSignal()) - << "signal should actually have been written"; - EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. equal timeout because FD was no longer registered"; - EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result) - << "pollOnce result should be ALOOPER_POLL_TIMEOUT"; - EXPECT_EQ(0, handler.callbackCount) - << "callback should not be invoked"; -} - -TEST_F(LooperTest, PollOnce_WhenCallbackReturnsFalse_CallbackShouldNotBeInvokedAgainLater) { - Pipe pipe; - StubCallbackHandler handler(false); - - handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); - - // First loop: Callback is registered and FD is signalled. - pipe.writeSignal(); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(0); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - ASSERT_EQ(OK, pipe.readSignal()) - << "signal should actually have been written"; - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. equal zero because FD was already signalled"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled"; - EXPECT_EQ(1, handler.callbackCount) - << "callback should be invoked"; - - // Second loop: Callback is no longer registered and FD is signalled. - pipe.writeSignal(); - - stopWatch.reset(); - result = mLooper->pollOnce(0); - elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - ASSERT_EQ(OK, pipe.readSignal()) - << "signal should actually have been written"; - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. equal zero because timeout was zero"; - EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result) - << "pollOnce result should be ALOOPER_POLL_TIMEOUT"; - EXPECT_EQ(1, handler.callbackCount) - << "callback should not be invoked this time"; -} - -TEST_F(LooperTest, PollOnce_WhenNonCallbackFdIsSignalled_ReturnsIdent) { - const int expectedIdent = 5; - void* expectedData = this; - - Pipe pipe; - - pipe.writeSignal(); - mLooper->addFd(pipe.receiveFd, expectedIdent, ALOOPER_EVENT_INPUT, NULL, expectedData); - - StopWatch stopWatch("pollOnce"); - int fd; - int events; - void* data; - int result = mLooper->pollOnce(100, &fd, &events, &data); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - ASSERT_EQ(OK, pipe.readSignal()) - << "signal should actually have been written"; - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should be approx. zero"; - EXPECT_EQ(expectedIdent, result) - << "pollOnce result should be the ident of the FD that was signalled"; - EXPECT_EQ(pipe.receiveFd, fd) - << "pollOnce should have returned the received pipe fd"; - EXPECT_EQ(ALOOPER_EVENT_INPUT, events) - << "pollOnce should have returned ALOOPER_EVENT_INPUT as events"; - EXPECT_EQ(expectedData, data) - << "pollOnce should have returned the data"; -} - -TEST_F(LooperTest, AddFd_WhenCallbackAdded_ReturnsOne) { - Pipe pipe; - int result = mLooper->addFd(pipe.receiveFd, 0, ALOOPER_EVENT_INPUT, NULL, NULL); - - EXPECT_EQ(1, result) - << "addFd should return 1 because FD was added"; -} - -TEST_F(LooperTest, AddFd_WhenIdentIsNegativeAndCallbackIsNull_ReturnsError) { - Pipe pipe; - int result = mLooper->addFd(pipe.receiveFd, -1, ALOOPER_EVENT_INPUT, NULL, NULL); - - EXPECT_EQ(-1, result) - << "addFd should return -1 because arguments were invalid"; -} - -TEST_F(LooperTest, AddFd_WhenNoCallbackAndAllowNonCallbacksIsFalse_ReturnsError) { - Pipe pipe; - sp<Looper> looper = new Looper(false /*allowNonCallbacks*/); - int result = looper->addFd(pipe.receiveFd, 0, 0, NULL, NULL); - - EXPECT_EQ(-1, result) - << "addFd should return -1 because arguments were invalid"; -} - -TEST_F(LooperTest, RemoveFd_WhenCallbackNotAdded_ReturnsZero) { - int result = mLooper->removeFd(1); - - EXPECT_EQ(0, result) - << "removeFd should return 0 because FD not registered"; -} - -TEST_F(LooperTest, RemoveFd_WhenCallbackAddedThenRemovedTwice_ReturnsOnceFirstTimeAndReturnsZeroSecondTime) { - Pipe pipe; - StubCallbackHandler handler(false); - handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); - - // First time. - int result = mLooper->removeFd(pipe.receiveFd); - - EXPECT_EQ(1, result) - << "removeFd should return 1 first time because FD was registered"; - - // Second time. - result = mLooper->removeFd(pipe.receiveFd); - - EXPECT_EQ(0, result) - << "removeFd should return 0 second time because FD was no longer registered"; -} - -TEST_F(LooperTest, PollOnce_WhenCallbackAddedTwice_OnlySecondCallbackShouldBeInvoked) { - Pipe pipe; - StubCallbackHandler handler1(true); - StubCallbackHandler handler2(true); - - handler1.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); - handler2.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); // replace it - pipe.writeSignal(); // would cause FD to be considered signalled - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(100); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - ASSERT_EQ(OK, pipe.readSignal()) - << "signal should actually have been written"; - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. zero because FD was already signalled"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because FD was signalled"; - EXPECT_EQ(0, handler1.callbackCount) - << "original handler callback should not be invoked because it was replaced"; - EXPECT_EQ(1, handler2.callbackCount) - << "replacement handler callback should be invoked"; -} - -TEST_F(LooperTest, SendMessage_WhenOneMessageIsEnqueue_ShouldInvokeHandlerDuringNextPoll) { - sp<StubMessageHandler> handler = new StubMessageHandler(); - mLooper->sendMessage(handler, Message(MSG_TEST1)); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(100); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. zero because message was already sent"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent"; - EXPECT_EQ(size_t(1), handler->messages.size()) - << "handled message"; - EXPECT_EQ(MSG_TEST1, handler->messages[0].what) - << "handled message"; -} - -TEST_F(LooperTest, SendMessage_WhenMultipleMessagesAreEnqueued_ShouldInvokeHandlersInOrderDuringNextPoll) { - sp<StubMessageHandler> handler1 = new StubMessageHandler(); - sp<StubMessageHandler> handler2 = new StubMessageHandler(); - mLooper->sendMessage(handler1, Message(MSG_TEST1)); - mLooper->sendMessage(handler2, Message(MSG_TEST2)); - mLooper->sendMessage(handler1, Message(MSG_TEST3)); - mLooper->sendMessage(handler1, Message(MSG_TEST4)); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(1000); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. zero because message was already sent"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent"; - EXPECT_EQ(size_t(3), handler1->messages.size()) - << "handled message"; - EXPECT_EQ(MSG_TEST1, handler1->messages[0].what) - << "handled message"; - EXPECT_EQ(MSG_TEST3, handler1->messages[1].what) - << "handled message"; - EXPECT_EQ(MSG_TEST4, handler1->messages[2].what) - << "handled message"; - EXPECT_EQ(size_t(1), handler2->messages.size()) - << "handled message"; - EXPECT_EQ(MSG_TEST2, handler2->messages[0].what) - << "handled message"; -} - -TEST_F(LooperTest, SendMessageDelayed_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime) { - sp<StubMessageHandler> handler = new StubMessageHandler(); - mLooper->sendMessageDelayed(ms2ns(100), handler, Message(MSG_TEST1)); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(1000); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "first poll should end quickly because next message timeout was computed"; - EXPECT_EQ(ALOOPER_POLL_WAKE, result) - << "pollOnce result should be ALOOPER_POLL_WAKE due to wakeup"; - EXPECT_EQ(size_t(0), handler->messages.size()) - << "no message handled yet"; - - result = mLooper->pollOnce(1000); - elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_EQ(size_t(1), handler->messages.size()) - << "handled message"; - EXPECT_EQ(MSG_TEST1, handler->messages[0].what) - << "handled message"; - EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS) - << "second poll should end around the time of the delayed message dispatch"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent"; - - result = mLooper->pollOnce(100); - elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(100 + 100, elapsedMillis, TIMING_TOLERANCE_MS) - << "third poll should timeout"; - EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result) - << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there were no messages left"; -} - -TEST_F(LooperTest, SendMessageDelayed_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll) { - sp<StubMessageHandler> handler = new StubMessageHandler(); - mLooper->sendMessageDelayed(ms2ns(-1000), handler, Message(MSG_TEST1)); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(100); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. zero because message was already sent"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent"; - EXPECT_EQ(size_t(1), handler->messages.size()) - << "handled message"; - EXPECT_EQ(MSG_TEST1, handler->messages[0].what) - << "handled message"; -} - -TEST_F(LooperTest, SendMessageDelayed_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll) { - sp<StubMessageHandler> handler = new StubMessageHandler(); - mLooper->sendMessageDelayed(0, handler, Message(MSG_TEST1)); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(100); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. zero because message was already sent"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent"; - EXPECT_EQ(size_t(1), handler->messages.size()) - << "handled message"; - EXPECT_EQ(MSG_TEST1, handler->messages[0].what) - << "handled message"; -} - -TEST_F(LooperTest, SendMessageAtTime_WhenSentToTheFuture_ShouldInvokeHandlerAfterDelayTime) { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - sp<StubMessageHandler> handler = new StubMessageHandler(); - mLooper->sendMessageAtTime(now + ms2ns(100), handler, Message(MSG_TEST1)); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(1000); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "first poll should end quickly because next message timeout was computed"; - EXPECT_EQ(ALOOPER_POLL_WAKE, result) - << "pollOnce result should be ALOOPER_POLL_WAKE due to wakeup"; - EXPECT_EQ(size_t(0), handler->messages.size()) - << "no message handled yet"; - - result = mLooper->pollOnce(1000); - elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_EQ(size_t(1), handler->messages.size()) - << "handled message"; - EXPECT_EQ(MSG_TEST1, handler->messages[0].what) - << "handled message"; - EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS) - << "second poll should end around the time of the delayed message dispatch"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent"; - - result = mLooper->pollOnce(100); - elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(100 + 100, elapsedMillis, TIMING_TOLERANCE_MS) - << "third poll should timeout"; - EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result) - << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there were no messages left"; -} - -TEST_F(LooperTest, SendMessageAtTime_WhenSentToThePast_ShouldInvokeHandlerDuringNextPoll) { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - sp<StubMessageHandler> handler = new StubMessageHandler(); - mLooper->sendMessageAtTime(now - ms2ns(1000), handler, Message(MSG_TEST1)); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(100); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. zero because message was already sent"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent"; - EXPECT_EQ(size_t(1), handler->messages.size()) - << "handled message"; - EXPECT_EQ(MSG_TEST1, handler->messages[0].what) - << "handled message"; -} - -TEST_F(LooperTest, SendMessageAtTime_WhenSentToThePresent_ShouldInvokeHandlerDuringNextPoll) { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - sp<StubMessageHandler> handler = new StubMessageHandler(); - mLooper->sendMessageAtTime(now, handler, Message(MSG_TEST1)); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(100); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. zero because message was already sent"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because message was sent"; - EXPECT_EQ(size_t(1), handler->messages.size()) - << "handled message"; - EXPECT_EQ(MSG_TEST1, handler->messages[0].what) - << "handled message"; -} - -TEST_F(LooperTest, RemoveMessage_WhenRemovingAllMessagesForHandler_ShouldRemoveThoseMessage) { - sp<StubMessageHandler> handler = new StubMessageHandler(); - mLooper->sendMessage(handler, Message(MSG_TEST1)); - mLooper->sendMessage(handler, Message(MSG_TEST2)); - mLooper->sendMessage(handler, Message(MSG_TEST3)); - mLooper->removeMessages(handler); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(0); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. zero because message was sent so looper was awoken"; - EXPECT_EQ(ALOOPER_POLL_WAKE, result) - << "pollOnce result should be ALOOPER_POLL_WAKE because looper was awoken"; - EXPECT_EQ(size_t(0), handler->messages.size()) - << "no messages to handle"; - - result = mLooper->pollOnce(0); - - EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result) - << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there was nothing to do"; - EXPECT_EQ(size_t(0), handler->messages.size()) - << "no messages to handle"; -} - -TEST_F(LooperTest, RemoveMessage_WhenRemovingSomeMessagesForHandler_ShouldRemoveThoseMessage) { - sp<StubMessageHandler> handler = new StubMessageHandler(); - mLooper->sendMessage(handler, Message(MSG_TEST1)); - mLooper->sendMessage(handler, Message(MSG_TEST2)); - mLooper->sendMessage(handler, Message(MSG_TEST3)); - mLooper->sendMessage(handler, Message(MSG_TEST4)); - mLooper->removeMessages(handler, MSG_TEST3); - mLooper->removeMessages(handler, MSG_TEST1); - - StopWatch stopWatch("pollOnce"); - int result = mLooper->pollOnce(0); - int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); - - EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS) - << "elapsed time should approx. zero because message was sent so looper was awoken"; - EXPECT_EQ(ALOOPER_POLL_CALLBACK, result) - << "pollOnce result should be ALOOPER_POLL_CALLBACK because two messages were sent"; - EXPECT_EQ(size_t(2), handler->messages.size()) - << "no messages to handle"; - EXPECT_EQ(MSG_TEST2, handler->messages[0].what) - << "handled message"; - EXPECT_EQ(MSG_TEST4, handler->messages[1].what) - << "handled message"; - - result = mLooper->pollOnce(0); - - EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result) - << "pollOnce result should be ALOOPER_POLL_TIMEOUT because there was nothing to do"; - EXPECT_EQ(size_t(2), handler->messages.size()) - << "no more messages to handle"; -} - -} // namespace android diff --git a/libs/utils/tests/LruCache_test.cpp b/libs/utils/tests/LruCache_test.cpp deleted file mode 100644 index e573952..0000000 --- a/libs/utils/tests/LruCache_test.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -#include <stdlib.h> -#include <utils/JenkinsHash.h> -#include <utils/LruCache.h> -#include <cutils/log.h> -#include <gtest/gtest.h> - -namespace android { - -typedef int SimpleKey; -typedef const char* StringValue; - -struct ComplexKey { - int k; - - explicit ComplexKey(int k) : k(k) { - instanceCount += 1; - } - - ComplexKey(const ComplexKey& other) : k(other.k) { - instanceCount += 1; - } - - ~ComplexKey() { - instanceCount -= 1; - } - - bool operator ==(const ComplexKey& other) const { - return k == other.k; - } - - bool operator !=(const ComplexKey& other) const { - return k != other.k; - } - - static ssize_t instanceCount; -}; - -ssize_t ComplexKey::instanceCount = 0; - -template<> inline hash_t hash_type(const ComplexKey& value) { - return hash_type(value.k); -} - -struct ComplexValue { - int v; - - explicit ComplexValue(int v) : v(v) { - instanceCount += 1; - } - - ComplexValue(const ComplexValue& other) : v(other.v) { - instanceCount += 1; - } - - ~ComplexValue() { - instanceCount -= 1; - } - - static ssize_t instanceCount; -}; - -ssize_t ComplexValue::instanceCount = 0; - -typedef LruCache<ComplexKey, ComplexValue> ComplexCache; - -class EntryRemovedCallback : public OnEntryRemoved<SimpleKey, StringValue> { -public: - EntryRemovedCallback() : callbackCount(0), lastKey(-1), lastValue(NULL) { } - ~EntryRemovedCallback() {} - void operator()(SimpleKey& k, StringValue& v) { - callbackCount += 1; - lastKey = k; - lastValue = v; - } - ssize_t callbackCount; - SimpleKey lastKey; - StringValue lastValue; -}; - -class LruCacheTest : public testing::Test { -protected: - virtual void SetUp() { - ComplexKey::instanceCount = 0; - ComplexValue::instanceCount = 0; - } - - virtual void TearDown() { - ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); - } - - void assertInstanceCount(ssize_t keys, ssize_t values) { - if (keys != ComplexKey::instanceCount || values != ComplexValue::instanceCount) { - FAIL() << "Expected " << keys << " keys and " << values << " values " - "but there were actually " << ComplexKey::instanceCount << " keys and " - << ComplexValue::instanceCount << " values"; - } - } -}; - -TEST_F(LruCacheTest, Empty) { - LruCache<SimpleKey, StringValue> cache(100); - - EXPECT_EQ(NULL, cache.get(0)); - EXPECT_EQ(0u, cache.size()); -} - -TEST_F(LruCacheTest, Simple) { - LruCache<SimpleKey, StringValue> cache(100); - - cache.put(1, "one"); - cache.put(2, "two"); - cache.put(3, "three"); - EXPECT_STREQ("one", cache.get(1)); - EXPECT_STREQ("two", cache.get(2)); - EXPECT_STREQ("three", cache.get(3)); - EXPECT_EQ(3u, cache.size()); -} - -TEST_F(LruCacheTest, MaxCapacity) { - LruCache<SimpleKey, StringValue> cache(2); - - cache.put(1, "one"); - cache.put(2, "two"); - cache.put(3, "three"); - EXPECT_EQ(NULL, cache.get(1)); - EXPECT_STREQ("two", cache.get(2)); - EXPECT_STREQ("three", cache.get(3)); - EXPECT_EQ(2u, cache.size()); -} - -TEST_F(LruCacheTest, RemoveLru) { - LruCache<SimpleKey, StringValue> cache(100); - - cache.put(1, "one"); - cache.put(2, "two"); - cache.put(3, "three"); - cache.removeOldest(); - EXPECT_EQ(NULL, cache.get(1)); - EXPECT_STREQ("two", cache.get(2)); - EXPECT_STREQ("three", cache.get(3)); - EXPECT_EQ(2u, cache.size()); -} - -TEST_F(LruCacheTest, GetUpdatesLru) { - LruCache<SimpleKey, StringValue> cache(100); - - cache.put(1, "one"); - cache.put(2, "two"); - cache.put(3, "three"); - EXPECT_STREQ("one", cache.get(1)); - cache.removeOldest(); - EXPECT_STREQ("one", cache.get(1)); - EXPECT_EQ(NULL, cache.get(2)); - EXPECT_STREQ("three", cache.get(3)); - EXPECT_EQ(2u, cache.size()); -} - -uint32_t hash_int(int x) { - return JenkinsHashWhiten(JenkinsHashMix(0, x)); -} - -TEST_F(LruCacheTest, StressTest) { - const size_t kCacheSize = 512; - LruCache<SimpleKey, StringValue> cache(512); - const size_t kNumKeys = 16 * 1024; - const size_t kNumIters = 100000; - char* strings[kNumKeys]; - - for (size_t i = 0; i < kNumKeys; i++) { - strings[i] = (char *)malloc(16); - sprintf(strings[i], "%d", i); - } - - srandom(12345); - int hitCount = 0; - for (size_t i = 0; i < kNumIters; i++) { - int index = random() % kNumKeys; - uint32_t key = hash_int(index); - const char *val = cache.get(key); - if (val != NULL) { - EXPECT_EQ(strings[index], val); - hitCount++; - } else { - cache.put(key, strings[index]); - } - } - size_t expectedHitCount = kNumIters * kCacheSize / kNumKeys; - EXPECT_LT(int(expectedHitCount * 0.9), hitCount); - EXPECT_GT(int(expectedHitCount * 1.1), hitCount); - EXPECT_EQ(kCacheSize, cache.size()); - - for (size_t i = 0; i < kNumKeys; i++) { - free((void *)strings[i]); - } -} - -TEST_F(LruCacheTest, NoLeak) { - ComplexCache cache(100); - - cache.put(ComplexKey(0), ComplexValue(0)); - cache.put(ComplexKey(1), ComplexValue(1)); - EXPECT_EQ(2, cache.size()); - assertInstanceCount(2, 3); // the null value counts as an instance -} - -TEST_F(LruCacheTest, Clear) { - ComplexCache cache(100); - - cache.put(ComplexKey(0), ComplexValue(0)); - cache.put(ComplexKey(1), ComplexValue(1)); - EXPECT_EQ(2, cache.size()); - assertInstanceCount(2, 3); - cache.clear(); - assertInstanceCount(0, 1); -} - -TEST_F(LruCacheTest, ClearNoDoubleFree) { - { - ComplexCache cache(100); - - cache.put(ComplexKey(0), ComplexValue(0)); - cache.put(ComplexKey(1), ComplexValue(1)); - EXPECT_EQ(2, cache.size()); - assertInstanceCount(2, 3); - cache.removeOldest(); - cache.clear(); - assertInstanceCount(0, 1); - } - assertInstanceCount(0, 0); -} - -TEST_F(LruCacheTest, ClearReuseOk) { - ComplexCache cache(100); - - cache.put(ComplexKey(0), ComplexValue(0)); - cache.put(ComplexKey(1), ComplexValue(1)); - EXPECT_EQ(2, cache.size()); - assertInstanceCount(2, 3); - cache.clear(); - assertInstanceCount(0, 1); - cache.put(ComplexKey(0), ComplexValue(0)); - cache.put(ComplexKey(1), ComplexValue(1)); - EXPECT_EQ(2, cache.size()); - assertInstanceCount(2, 3); -} - -TEST_F(LruCacheTest, Callback) { - LruCache<SimpleKey, StringValue> cache(100); - EntryRemovedCallback callback; - cache.setOnEntryRemovedListener(&callback); - - cache.put(1, "one"); - cache.put(2, "two"); - cache.put(3, "three"); - EXPECT_EQ(3, cache.size()); - cache.removeOldest(); - EXPECT_EQ(1, callback.callbackCount); - EXPECT_EQ(1, callback.lastKey); - EXPECT_STREQ("one", callback.lastValue); -} - -TEST_F(LruCacheTest, CallbackOnClear) { - LruCache<SimpleKey, StringValue> cache(100); - EntryRemovedCallback callback; - cache.setOnEntryRemovedListener(&callback); - - cache.put(1, "one"); - cache.put(2, "two"); - cache.put(3, "three"); - EXPECT_EQ(3, cache.size()); - cache.clear(); - EXPECT_EQ(3, callback.callbackCount); -} - -} diff --git a/libs/utils/tests/String8_test.cpp b/libs/utils/tests/String8_test.cpp deleted file mode 100644 index c42c68d..0000000 --- a/libs/utils/tests/String8_test.cpp +++ /dev/null @@ -1,75 +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. - */ - -#define LOG_TAG "String8_test" -#include <utils/Log.h> -#include <utils/String8.h> - -#include <gtest/gtest.h> - -namespace android { - -class String8Test : public testing::Test { -protected: - virtual void SetUp() { - } - - virtual void TearDown() { - } -}; - -TEST_F(String8Test, Cstr) { - String8 tmp("Hello, world!"); - - EXPECT_STREQ(tmp.string(), "Hello, world!"); -} - -TEST_F(String8Test, OperatorPlus) { - String8 src1("Hello, "); - - // Test adding String8 + const char* - const char* ccsrc2 = "world!"; - String8 dst1 = src1 + ccsrc2; - EXPECT_STREQ(dst1.string(), "Hello, world!"); - EXPECT_STREQ(src1.string(), "Hello, "); - EXPECT_STREQ(ccsrc2, "world!"); - - // Test adding String8 + String8 - String8 ssrc2("world!"); - String8 dst2 = src1 + ssrc2; - EXPECT_STREQ(dst2.string(), "Hello, world!"); - EXPECT_STREQ(src1.string(), "Hello, "); - EXPECT_STREQ(ssrc2.string(), "world!"); -} - -TEST_F(String8Test, OperatorPlusEquals) { - String8 src1("My voice"); - - // Testing String8 += String8 - String8 src2(" is my passport."); - src1 += src2; - EXPECT_STREQ(src1.string(), "My voice is my passport."); - EXPECT_STREQ(src2.string(), " is my passport."); - - // Adding const char* to the previous string. - const char* src3 = " Verify me."; - src1 += src3; - EXPECT_STREQ(src1.string(), "My voice is my passport. Verify me."); - EXPECT_STREQ(src2.string(), " is my passport."); - EXPECT_STREQ(src3, " Verify me."); -} - -} diff --git a/libs/utils/tests/TestHelpers.h b/libs/utils/tests/TestHelpers.h deleted file mode 100644 index d8e985e..0000000 --- a/libs/utils/tests/TestHelpers.h +++ /dev/null @@ -1,79 +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 TESTHELPERS_H -#define TESTHELPERS_H - -#include <utils/threads.h> - -namespace android { - -class Pipe { -public: - int sendFd; - int receiveFd; - - Pipe() { - int fds[2]; - ::pipe(fds); - - receiveFd = fds[0]; - sendFd = fds[1]; - } - - ~Pipe() { - if (sendFd != -1) { - ::close(sendFd); - } - - if (receiveFd != -1) { - ::close(receiveFd); - } - } - - status_t writeSignal() { - ssize_t nWritten = ::write(sendFd, "*", 1); - return nWritten == 1 ? 0 : -errno; - } - - status_t readSignal() { - char buf[1]; - ssize_t nRead = ::read(receiveFd, buf, 1); - return nRead == 1 ? 0 : nRead == 0 ? -EPIPE : -errno; - } -}; - -class DelayedTask : public Thread { - int mDelayMillis; - -public: - DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { } - -protected: - virtual ~DelayedTask() { } - - virtual void doTask() = 0; - - virtual bool threadLoop() { - usleep(mDelayMillis * 1000); - doTask(); - return false; - } -}; - -} // namespace android - -#endif // TESTHELPERS_H diff --git a/libs/utils/tests/Unicode_test.cpp b/libs/utils/tests/Unicode_test.cpp deleted file mode 100644 index 18c130c..0000000 --- a/libs/utils/tests/Unicode_test.cpp +++ /dev/null @@ -1,115 +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. - */ - -#define LOG_TAG "Unicode_test" -#include <utils/Log.h> -#include <utils/Unicode.h> - -#include <gtest/gtest.h> - -namespace android { - -class UnicodeTest : public testing::Test { -protected: - virtual void SetUp() { - } - - virtual void TearDown() { - } -}; - -TEST_F(UnicodeTest, UTF8toUTF16ZeroLength) { - ssize_t measured; - - const uint8_t str[] = { }; - - measured = utf8_to_utf16_length(str, 0); - EXPECT_EQ(0, measured) - << "Zero length input should return zero length output."; -} - -TEST_F(UnicodeTest, UTF8toUTF16ASCIILength) { - ssize_t measured; - - // U+0030 or ASCII '0' - const uint8_t str[] = { 0x30 }; - - measured = utf8_to_utf16_length(str, sizeof(str)); - EXPECT_EQ(1, measured) - << "ASCII glyphs should have a length of 1 char16_t"; -} - -TEST_F(UnicodeTest, UTF8toUTF16Plane1Length) { - ssize_t measured; - - // U+2323 SMILE - const uint8_t str[] = { 0xE2, 0x8C, 0xA3 }; - - measured = utf8_to_utf16_length(str, sizeof(str)); - EXPECT_EQ(1, measured) - << "Plane 1 glyphs should have a length of 1 char16_t"; -} - -TEST_F(UnicodeTest, UTF8toUTF16SurrogateLength) { - ssize_t measured; - - // U+10000 - const uint8_t str[] = { 0xF0, 0x90, 0x80, 0x80 }; - - measured = utf8_to_utf16_length(str, sizeof(str)); - EXPECT_EQ(2, measured) - << "Surrogate pairs should have a length of 2 char16_t"; -} - -TEST_F(UnicodeTest, UTF8toUTF16TruncatedUTF8) { - ssize_t measured; - - // Truncated U+2323 SMILE - // U+2323 SMILE - const uint8_t str[] = { 0xE2, 0x8C }; - - measured = utf8_to_utf16_length(str, sizeof(str)); - EXPECT_EQ(-1, measured) - << "Truncated UTF-8 should return -1 to indicate invalid"; -} - -TEST_F(UnicodeTest, UTF8toUTF16Normal) { - const uint8_t str[] = { - 0x30, // U+0030, 1 UTF-16 character - 0xC4, 0x80, // U+0100, 1 UTF-16 character - 0xE2, 0x8C, 0xA3, // U+2323, 1 UTF-16 character - 0xF0, 0x90, 0x80, 0x80, // U+10000, 2 UTF-16 character - }; - - char16_t output[1 + 1 + 1 + 2 + 1]; // Room for NULL - - utf8_to_utf16(str, sizeof(str), output); - - EXPECT_EQ(0x0030, output[0]) - << "should be U+0030"; - EXPECT_EQ(0x0100, output[1]) - << "should be U+0100"; - EXPECT_EQ(0x2323, output[2]) - << "should be U+2323"; - EXPECT_EQ(0xD800, output[3]) - << "should be first half of surrogate U+10000"; - EXPECT_EQ(0xDC00, output[4]) - << "should be second half of surrogate U+10000"; - EXPECT_EQ(NULL, output[5]) - << "should be NULL terminated"; -} - -} diff --git a/libs/utils/tests/Vector_test.cpp b/libs/utils/tests/Vector_test.cpp deleted file mode 100644 index d29c054..0000000 --- a/libs/utils/tests/Vector_test.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2012 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 "Vector_test" - -#include <utils/Vector.h> -#include <cutils/log.h> -#include <gtest/gtest.h> -#include <unistd.h> - -namespace android { - -class VectorTest : public testing::Test { -protected: - virtual void SetUp() { - } - - virtual void TearDown() { - } - -public: -}; - - -TEST_F(VectorTest, CopyOnWrite_CopyAndAddElements) { - - Vector<int> vector; - Vector<int> other; - vector.setCapacity(8); - - vector.add(1); - vector.add(2); - vector.add(3); - - EXPECT_EQ(vector.size(), 3); - - // copy the vector - other = vector; - - EXPECT_EQ(other.size(), 3); - - // add an element to the first vector - vector.add(4); - - // make sure the sizes are correct - EXPECT_EQ(vector.size(), 4); - EXPECT_EQ(other.size(), 3); - - // add an element to the copy - other.add(5); - - // make sure the sizes are correct - EXPECT_EQ(vector.size(), 4); - EXPECT_EQ(other.size(), 4); - - // make sure the content of both vectors are correct - EXPECT_EQ(vector[3], 4); - EXPECT_EQ(other[3], 5); -} - - -} // namespace android |