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