From 4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 21 Oct 2008 07:00:00 -0700 Subject: Initial Contribution --- libpixelflinger/codeflinger/CodeCache.cpp | 151 ++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 libpixelflinger/codeflinger/CodeCache.cpp (limited to 'libpixelflinger/codeflinger/CodeCache.cpp') 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 +#include +#include + +#include +#include + +#include "codeflinger/CodeCache.h" + +namespace android { + +// ---------------------------------------------------------------------------- + +#if defined(__arm__) +#include +#include +#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 CodeCache::lookup(const AssemblyKeyBase& keyBase) const +{ + pthread_mutex_lock(&mLock); + sp 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) +{ + 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 ; isize(); + 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 -- cgit v1.1