diff options
| author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:14 -0800 |
|---|---|---|
| committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:14 -0800 |
| commit | f72d5de56a522ac3be03873bdde26f23a5eeeb3c (patch) | |
| tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /vm/AtomicCache.c | |
| parent | 31e30105703263782efd450d356cd67ea01af3b7 (diff) | |
| download | android_dalvik-f72d5de56a522ac3be03873bdde26f23a5eeeb3c.tar.gz android_dalvik-f72d5de56a522ac3be03873bdde26f23a5eeeb3c.tar.bz2 android_dalvik-f72d5de56a522ac3be03873bdde26f23a5eeeb3c.zip | |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'vm/AtomicCache.c')
| -rw-r--r-- | vm/AtomicCache.c | 173 |
1 files changed, 0 insertions, 173 deletions
diff --git a/vm/AtomicCache.c b/vm/AtomicCache.c deleted file mode 100644 index cee84a892..000000000 --- a/vm/AtomicCache.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2008 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. - */ -/* - * Mutex-free cache. Each entry has two 32-bit keys, one 32-bit value, - * and a 32-bit version. - */ -#include "Dalvik.h" - -#include <stdlib.h> - -/* - * I think modern C mandates that the results of a boolean expression are - * 0 or 1. If not, or we suddenly turn into C++ and bool != int, use this. - */ -#define BOOL_TO_INT(x) (x) -//#define BOOL_TO_INT(x) ((x) ? 1 : 0) - -#define CPU_CACHE_WIDTH 32 -#define CPU_CACHE_WIDTH_1 (CPU_CACHE_WIDTH-1) - -#define ATOMIC_LOCK_FLAG (1 << 31) - -/* - * Allocate cache. - */ -AtomicCache* dvmAllocAtomicCache(int numEntries) -{ - AtomicCache* newCache; - - newCache = (AtomicCache*) calloc(1, sizeof(AtomicCache)); - if (newCache == NULL) - return NULL; - - newCache->numEntries = numEntries; - - newCache->entryAlloc = calloc(1, - sizeof(AtomicCacheEntry) * numEntries + CPU_CACHE_WIDTH); - if (newCache->entryAlloc == NULL) - return NULL; - - /* - * Adjust storage to align on a 32-byte boundary. Each entry is 16 bytes - * wide. This ensures that each cache entry sits on a single CPU cache - * line. - */ - assert(sizeof(AtomicCacheEntry) == 16); - newCache->entries = (AtomicCacheEntry*) - (((int) newCache->entryAlloc + CPU_CACHE_WIDTH_1) & ~CPU_CACHE_WIDTH_1); - - return newCache; -} - -/* - * Free cache. - */ -void dvmFreeAtomicCache(AtomicCache* cache) -{ - if (cache != NULL) { - free(cache->entryAlloc); - free(cache); - } -} - - - -/* - * Update a cache entry. - * - * In the event of a collision with another thread, the update may be skipped. - * - * We only need "pCache" for stats. - */ -void dvmUpdateAtomicCache(u4 key1, u4 key2, u4 value, AtomicCacheEntry* pEntry, - u4 firstVersion -#if CALC_CACHE_STATS > 0 - , AtomicCache* pCache -#endif - ) -{ - /* - * The fields don't match, so we need to update them. There is a - * risk that another thread is also trying to update them, so we - * grab an ownership flag to lock out other threads. - * - * If the lock flag was already set in "firstVersion", somebody else - * was in mid-update. (This means that using "firstVersion" as the - * "before" argument to the CAS would succeed when it shouldn't and - * vice-versa -- we could also just pass in - * (firstVersion & ~ATOMIC_LOCK_FLAG) as the first argument.) - * - * NOTE: we don't really deal with the situation where we overflow - * the version counter (at 2^31). Probably not a real concern. - */ - if ((firstVersion & ATOMIC_LOCK_FLAG) != 0 || - !ATOMIC_CMP_SWAP((volatile s4*) &pEntry->version, - firstVersion, firstVersion | ATOMIC_LOCK_FLAG)) - { - /* - * We couldn't get the write lock. Return without updating the table. - */ -#if CALC_CACHE_STATS > 0 - pCache->fail++; -#endif - return; - } - - /* must be even-valued on entry */ - assert((firstVersion & 0x01) == 0); - -#if CALC_CACHE_STATS > 0 - /* for stats, assume a key value of zero indicates an empty entry */ - if (pEntry->key1 == 0) - pCache->fills++; - else - pCache->misses++; -#endif - - /* volatile incr */ - pEntry->version++; - MEM_BARRIER(); - - pEntry->key1 = key1; - pEntry->key2 = key2; - pEntry->value = value; - - /* volatile incr */ - pEntry->version++; - MEM_BARRIER(); - - /* - * Clear the lock flag. Nobody else should have been able to modify - * pEntry->version, so if this fails the world is broken. - */ - firstVersion += 2; - if (!ATOMIC_CMP_SWAP((volatile s4*) &pEntry->version, - firstVersion | ATOMIC_LOCK_FLAG, firstVersion)) - { - //LOGE("unable to reset the instanceof cache ownership\n"); - dvmAbort(); - } -} - - -/* - * Dump the "instanceof" cache stats. - */ -void dvmDumpAtomicCacheStats(const AtomicCache* pCache) -{ - if (pCache == NULL) - return; - dvmFprintf(stdout, - "Cache stats: trv=%d fai=%d hit=%d mis=%d fil=%d %d%% (size=%d)\n", - pCache->trivial, pCache->fail, pCache->hits, - pCache->misses, pCache->fills, - (pCache->hits == 0) ? 0 : - pCache->hits * 100 / - (pCache->fail + pCache->hits + pCache->misses + pCache->fills), - pCache->numEntries); -} - |
