1 /* libs/pixelflinger/codeflinger/CodeCache.cpp
3 ** Copyright 2006, The Android Open Source Project
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
9 ** http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <cutils/log.h>
24 #include <cutils/atomic.h>
26 #include "CodeCache.h" //codeflinger/
30 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 Assembly::Assembly(size_t size
)
42 mBase
= (uint32_t*)malloc(size
);
53 void Assembly::incStrong(const void*) const
55 android_atomic_inc(&mCount
);
58 void Assembly::decStrong(const void*) const
60 if (android_atomic_dec(&mCount
) == 1) {
65 ssize_t
Assembly::size() const
67 if (!mBase
) return NO_MEMORY
;
71 uint32_t* Assembly::base() const
76 ssize_t
Assembly::resize(size_t newSize
)
78 mBase
= (uint32_t*)realloc(mBase
, newSize
);
83 // ----------------------------------------------------------------------------
85 CodeCache::CodeCache(size_t size
)
86 : mCacheSize(size
), mCacheInUse(0)
88 pthread_mutex_init(&mLock
, 0);
91 CodeCache::~CodeCache()
93 pthread_mutex_destroy(&mLock
);
96 sp
<Assembly
> CodeCache::lookup(const AssemblyKeyBase
& keyBase
) const
98 pthread_mutex_lock(&mLock
);
100 ssize_t index
= mCacheData
.indexOfKey(key_t(keyBase
));
102 const cache_entry_t
& e
= mCacheData
.valueAt(index
);
106 pthread_mutex_unlock(&mLock
);
110 int CodeCache::cache( const AssemblyKeyBase
& keyBase
,
111 const sp
<Assembly
>& assembly
)
113 pthread_mutex_lock(&mLock
);
115 const ssize_t assemblySize
= assembly
->size();
116 while (mCacheInUse
+ assemblySize
> mCacheSize
) {
119 size_t count
= mCacheData
.size();
120 for (size_t i
=0 ; i
<count
; i
++) {
121 const cache_entry_t
& e
= mCacheData
.valueAt(i
);
122 if (e
.when
< mCacheData
.valueAt(lru
).when
) {
126 const cache_entry_t
& e
= mCacheData
.valueAt(lru
);
127 mCacheInUse
-= e
.entry
->size();
128 mCacheData
.removeItemsAt(lru
);
131 ssize_t err
= mCacheData
.add(key_t(keyBase
), cache_entry_t(assembly
, mWhen
));
133 mCacheInUse
+= assemblySize
;
135 // synchronize caches...
136 #if 0 //defined(__arm__) /* liunote cacheflush bonic libc funcion , gcc not this func !!!*/
137 const long base
= long(assembly
->base());
138 const long curr
= base
+ long(assembly
->size());
139 err
= cacheflush(base
, curr
, 0);
140 LOGE_IF(err
, "__ARM_NR_cacheflush error %s\n",
145 pthread_mutex_unlock(&mLock
);
149 // ----------------------------------------------------------------------------
151 }; // namespace android