| /* libs/pixelflinger/codeflinger/CodeCache.h |
| ** |
| ** Copyright 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 ANDROID_CODECACHE_H |
| #define ANDROID_CODECACHE_H |
| |
| #include <atomic> |
| #include <stdint.h> |
| #include <pthread.h> |
| #include <sys/types.h> |
| |
| #include "utils/KeyedVector.h" |
| #include "tinyutils/smartpointer.h" |
| |
| namespace android { |
| |
| using namespace tinyutils; |
| |
| // ---------------------------------------------------------------------------- |
| |
| class AssemblyKeyBase { |
| public: |
| virtual ~AssemblyKeyBase() { } |
| virtual int compare_type(const AssemblyKeyBase& key) const = 0; |
| }; |
| |
| template <typename T> |
| class AssemblyKey : public AssemblyKeyBase |
| { |
| public: |
| explicit AssemblyKey(const T& rhs) : mKey(rhs) { } |
| virtual int compare_type(const AssemblyKeyBase& key) const { |
| const T& rhs = static_cast<const AssemblyKey&>(key).mKey; |
| return android::compare_type(mKey, rhs); |
| } |
| private: |
| T mKey; |
| }; |
| |
| // ---------------------------------------------------------------------------- |
| |
| class Assembly |
| { |
| public: |
| explicit Assembly(size_t size); |
| virtual ~Assembly(); |
| |
| ssize_t size() const; |
| uint32_t* base() const; |
| ssize_t resize(size_t size); |
| |
| // protocol for sp<> |
| void incStrong(const void* id) const; |
| void decStrong(const void* id) const; |
| typedef void weakref_type; |
| |
| private: |
| mutable std::atomic<int32_t> mCount; |
| uint32_t* mBase; |
| size_t mSize; |
| }; |
| |
| // ---------------------------------------------------------------------------- |
| |
| class CodeCache |
| { |
| public: |
| // pretty simple cache API... |
| explicit CodeCache(size_t size); |
| ~CodeCache(); |
| |
| sp<Assembly> lookup(const AssemblyKeyBase& key) const; |
| |
| int cache(const AssemblyKeyBase& key, |
| const sp<Assembly>& assembly); |
| |
| private: |
| // nothing to see here... |
| struct cache_entry_t { |
| inline cache_entry_t() { } |
| inline cache_entry_t(const sp<Assembly>& a, int64_t w) |
| : entry(a), when(w) { } |
| sp<Assembly> entry; |
| mutable int64_t when; |
| }; |
| |
| class key_t { |
| friend int compare_type( |
| const key_value_pair_t<key_t, cache_entry_t>&, |
| const key_value_pair_t<key_t, cache_entry_t>&); |
| const AssemblyKeyBase* mKey; |
| public: |
| key_t() { }; |
| explicit key_t(const AssemblyKeyBase& k) : mKey(&k) { } |
| }; |
| |
| mutable pthread_mutex_t mLock; |
| mutable int64_t mWhen; |
| size_t mCacheSize; |
| size_t mCacheInUse; |
| KeyedVector<key_t, cache_entry_t> mCacheData; |
| |
| friend int compare_type( |
| const key_value_pair_t<key_t, cache_entry_t>&, |
| const key_value_pair_t<key_t, cache_entry_t>&); |
| }; |
| |
| // KeyedVector uses compare_type(), which is more efficient, than |
| // just using operator < () |
| inline int compare_type( |
| const key_value_pair_t<CodeCache::key_t, CodeCache::cache_entry_t>& lhs, |
| const key_value_pair_t<CodeCache::key_t, CodeCache::cache_entry_t>& rhs) |
| { |
| return lhs.key.mKey->compare_type(*(rhs.key.mKey)); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| }; // namespace android |
| |
| #endif //ANDROID_CODECACHE_H |