summaryrefslogtreecommitdiffstats
path: root/vm/AtomicCache.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:14 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:14 -0800
commitf72d5de56a522ac3be03873bdde26f23a5eeeb3c (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /vm/AtomicCache.c
parent31e30105703263782efd450d356cd67ea01af3b7 (diff)
downloadandroid_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.c173
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);
-}
-