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 <stdint.h>
23 #include <pthread.h>
24 #include <sys/types.h>
25
26 #include "tinyutils/KeyedVector.h"
27 #include "tinyutils/smartpointer.h"
28
29 namespace android {
30
31 // ----------------------------------------------------------------------------
32
33 class AssemblyKeyBase {
34 public:
~AssemblyKeyBase()35 virtual ~AssemblyKeyBase() { }
36 virtual int compare_type(const AssemblyKeyBase& key) const = 0;
37 };
38
39 template <typename T>
40 class AssemblyKey : public AssemblyKeyBase
41 {
42 public:
AssemblyKey(const T & rhs)43 AssemblyKey(const T& rhs) : mKey(rhs) { }
compare_type(const AssemblyKeyBase & key)44 virtual int compare_type(const AssemblyKeyBase& key) const {
45 const T& rhs = static_cast<const AssemblyKey&>(key).mKey;
46 return android::compare_type(mKey, rhs);
47 }
48 private:
49 T mKey;
50 };
51
52 // ----------------------------------------------------------------------------
53
54 class Assembly
55 {
56 public:
57 Assembly(size_t size);
58 virtual ~Assembly();
59
60 ssize_t size() const;
61 uint32_t* base() const;
62 ssize_t resize(size_t size);
63
64 // protocol for sp<>
65 void incStrong(const void* id) const;
66 void decStrong(const void* id) const;
67 typedef void weakref_type;
68
69 private:
70 mutable int32_t mCount;
71 uint32_t* mBase;
72 size_t mSize;
73 };
74
75 // ----------------------------------------------------------------------------
76
77 class CodeCache
78 {
79 public:
80 // pretty simple cache API...
81 CodeCache(size_t size);
82 ~CodeCache();
83
84 sp<Assembly> lookup(const AssemblyKeyBase& key) const;
85
86 int cache( const AssemblyKeyBase& key,
87 const sp<Assembly>& assembly);
88
89 private:
90 // nothing to see here...
91 struct cache_entry_t {
cache_entry_tcache_entry_t92 inline cache_entry_t() { }
cache_entry_tcache_entry_t93 inline cache_entry_t(const sp<Assembly>& a, int64_t w)
94 : entry(a), when(w) { }
95 sp<Assembly> entry;
96 mutable int64_t when;
97 };
98
99 class key_t {
100 friend int compare_type(
101 const key_value_pair_t<key_t, cache_entry_t>&,
102 const key_value_pair_t<key_t, cache_entry_t>&);
103 const AssemblyKeyBase* mKey;
104 public:
key_t()105 key_t() { };
key_t(const AssemblyKeyBase & k)106 key_t(const AssemblyKeyBase& k) : mKey(&k) { }
107 };
108
109 mutable pthread_mutex_t mLock;
110 mutable int64_t mWhen;
111 size_t mCacheSize;
112 size_t mCacheInUse;
113 KeyedVector<key_t, cache_entry_t> mCacheData;
114
115 friend int compare_type(
116 const key_value_pair_t<key_t, cache_entry_t>&,
117 const key_value_pair_t<key_t, cache_entry_t>&);
118 };
119
120 // KeyedVector uses compare_type(), which is more efficient, than
121 // just using operator < ()
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)122 inline int compare_type(
123 const key_value_pair_t<CodeCache::key_t, CodeCache::cache_entry_t>& lhs,
124 const key_value_pair_t<CodeCache::key_t, CodeCache::cache_entry_t>& rhs)
125 {
126 return lhs.key.mKey->compare_type(*(rhs.key.mKey));
127 }
128
129 // ----------------------------------------------------------------------------
130
131 }; // namespace android
132
133 #endif //ANDROID_CODECACHE_H
134