1 /* libs/pixelflinger/codeflinger/CodeCache.h 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 19 #ifndef ANDROID_CODECACHE_H 20 #define ANDROID_CODECACHE_H 21 22 #include <atomic> 23 #include <stdint.h> 24 #include <pthread.h> 25 #include <sys/types.h> 26 27 #include "utils/KeyedVector.h" 28 #include "tinyutils/smartpointer.h" 29 30 namespace android { 31 32 using namespace tinyutils; 33 34 // ---------------------------------------------------------------------------- 35 36 class AssemblyKeyBase { 37 public: 38 virtual ~AssemblyKeyBase() { } 39 virtual int compare_type(const AssemblyKeyBase& key) const = 0; 40 }; 41 42 template <typename T> 43 class AssemblyKey : public AssemblyKeyBase 44 { 45 public: 46 explicit AssemblyKey(const T& rhs) : mKey(rhs) { } 47 virtual int compare_type(const AssemblyKeyBase& key) const { 48 const T& rhs = static_cast<const AssemblyKey&>(key).mKey; 49 return android::compare_type(mKey, rhs); 50 } 51 private: 52 T mKey; 53 }; 54 55 // ---------------------------------------------------------------------------- 56 57 class Assembly 58 { 59 public: 60 explicit Assembly(size_t size); 61 virtual ~Assembly(); 62 63 ssize_t size() const; 64 uint32_t* base() const; 65 ssize_t resize(size_t size); 66 67 // protocol for sp<> 68 void incStrong(const void* id) const; 69 void decStrong(const void* id) const; 70 typedef void weakref_type; 71 72 private: 73 mutable std::atomic<int32_t> mCount; 74 uint32_t* mBase; 75 size_t mSize; 76 }; 77 78 // ---------------------------------------------------------------------------- 79 80 class CodeCache 81 { 82 public: 83 // pretty simple cache API... 84 explicit CodeCache(size_t size); 85 ~CodeCache(); 86 87 sp<Assembly> lookup(const AssemblyKeyBase& key) const; 88 89 int cache(const AssemblyKeyBase& key, 90 const sp<Assembly>& assembly); 91 92 private: 93 // nothing to see here... 94 struct cache_entry_t { 95 inline cache_entry_t() { } 96 inline cache_entry_t(const sp<Assembly>& a, int64_t w) 97 : entry(a), when(w) { } 98 sp<Assembly> entry; 99 mutable int64_t when; 100 }; 101 102 class key_t { 103 friend int compare_type( 104 const key_value_pair_t<key_t, cache_entry_t>&, 105 const key_value_pair_t<key_t, cache_entry_t>&); 106 const AssemblyKeyBase* mKey; 107 public: 108 key_t() { }; 109 explicit key_t(const AssemblyKeyBase& k) : mKey(&k) { } 110 }; 111 112 mutable pthread_mutex_t mLock; 113 mutable int64_t mWhen; 114 size_t mCacheSize; 115 size_t mCacheInUse; 116 KeyedVector<key_t, cache_entry_t> mCacheData; 117 118 friend int compare_type( 119 const key_value_pair_t<key_t, cache_entry_t>&, 120 const key_value_pair_t<key_t, cache_entry_t>&); 121 }; 122 123 // KeyedVector uses compare_type(), which is more efficient, than 124 // just using operator < () 125 inline int compare_type( 126 const key_value_pair_t<CodeCache::key_t, CodeCache::cache_entry_t>& lhs, 127 const key_value_pair_t<CodeCache::key_t, CodeCache::cache_entry_t>& rhs) 128 { 129 return lhs.key.mKey->compare_type(*(rhs.key.mKey)); 130 } 131 132 // ---------------------------------------------------------------------------- 133 134 }; // namespace android 135 136 #endif //ANDROID_CODECACHE_H 137