diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:32:55 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:32:55 -0800 |
commit | dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0 (patch) | |
tree | 2ba8d1a0846d69b18f623515e8d9b5d9fe38b590 /libpixelflinger/codeflinger/CodeCache.cpp | |
parent | e54eebbf1a908d65ee8cf80bab62821c05666d70 (diff) | |
download | system_core-dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0.zip system_core-dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0.tar.gz system_core-dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'libpixelflinger/codeflinger/CodeCache.cpp')
-rw-r--r-- | libpixelflinger/codeflinger/CodeCache.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/libpixelflinger/codeflinger/CodeCache.cpp b/libpixelflinger/codeflinger/CodeCache.cpp new file mode 100644 index 0000000..29410c8 --- /dev/null +++ b/libpixelflinger/codeflinger/CodeCache.cpp @@ -0,0 +1,151 @@ +/* libs/pixelflinger/codeflinger/CodeCache.cpp +** +** 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. +*/ + + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +#include <cutils/log.h> +#include <cutils/atomic.h> + +#include "codeflinger/CodeCache.h" + +namespace android { + +// ---------------------------------------------------------------------------- + +#if defined(__arm__) +#include <unistd.h> +#include <errno.h> +#endif + +// ---------------------------------------------------------------------------- + +Assembly::Assembly(size_t size) + : mCount(1), mSize(0) +{ + mBase = (uint32_t*)malloc(size); + if (mBase) { + mSize = size; + } +} + +Assembly::~Assembly() +{ + free(mBase); +} + +void Assembly::incStrong(const void*) const +{ + android_atomic_inc(&mCount); +} + +void Assembly::decStrong(const void*) const +{ + if (android_atomic_dec(&mCount) == 1) { + delete this; + } +} + +ssize_t Assembly::size() const +{ + if (!mBase) return NO_MEMORY; + return mSize; +} + +uint32_t* Assembly::base() const +{ + return mBase; +} + +ssize_t Assembly::resize(size_t newSize) +{ + mBase = (uint32_t*)realloc(mBase, newSize); + mSize = newSize; + return size(); +} + +// ---------------------------------------------------------------------------- + +CodeCache::CodeCache(size_t size) + : mCacheSize(size), mCacheInUse(0) +{ + pthread_mutex_init(&mLock, 0); +} + +CodeCache::~CodeCache() +{ + pthread_mutex_destroy(&mLock); +} + +sp<Assembly> CodeCache::lookup(const AssemblyKeyBase& keyBase) const +{ + pthread_mutex_lock(&mLock); + sp<Assembly> r; + ssize_t index = mCacheData.indexOfKey(key_t(keyBase)); + if (index >= 0) { + const cache_entry_t& e = mCacheData.valueAt(index); + e.when = mWhen++; + r = e.entry; + } + pthread_mutex_unlock(&mLock); + return r; +} + +int CodeCache::cache( const AssemblyKeyBase& keyBase, + const sp<Assembly>& assembly) +{ + pthread_mutex_lock(&mLock); + + const ssize_t assemblySize = assembly->size(); + while (mCacheInUse + assemblySize > mCacheSize) { + // evict the LRU + size_t lru = 0; + size_t count = mCacheData.size(); + for (size_t i=0 ; i<count ; i++) { + const cache_entry_t& e = mCacheData.valueAt(i); + if (e.when < mCacheData.valueAt(lru).when) { + lru = i; + } + } + const cache_entry_t& e = mCacheData.valueAt(lru); + mCacheInUse -= e.entry->size(); + mCacheData.removeItemsAt(lru); + } + + ssize_t err = mCacheData.add(key_t(keyBase), cache_entry_t(assembly, mWhen)); + if (err >= 0) { + mCacheInUse += assemblySize; + mWhen++; + // synchronize caches... +#if defined(__arm__) + const long base = long(assembly->base()); + const long curr = base + long(assembly->size()); + err = cacheflush(base, curr, 0); + LOGE_IF(err, "__ARM_NR_cacheflush error %s\n", + strerror(errno)); +#endif + } + + pthread_mutex_unlock(&mLock); + return err; +} + +// ---------------------------------------------------------------------------- + +}; // namespace android |