OSDN Git Service

am beeeb788: am 05fa5fd5: Merge "Simplify merges of the annotation code."
[android-x86/dalvik.git] / vm / AtomicCache.h
index 66d222e..42ba6be 100644 (file)
@@ -16,8 +16,8 @@
 /*
  * Mutex-free cache for key1+key2=value.
  */
-#ifndef _DALVIK_ATOMICCACHE
-#define _DALVIK_ATOMICCACHE
+#ifndef DALVIK_ATOMICCACHE_H_
+#define DALVIK_ATOMICCACHE_H_
 
 /*
  * If set to "1", gather some stats on our caching success rate.
  *
  * Must be exactly 16 bytes.
  */
-typedef struct AtomicCacheEntry {
+struct AtomicCacheEntry {
     u4          key1;
     u4          key2;
     u4          value;
     volatile u4 version;    /* version and lock flag */
-} AtomicCacheEntry;
+};
 
 /*
  * One cache.
@@ -45,7 +45,7 @@ typedef struct AtomicCacheEntry {
  * struct and "entries" separately, avoiding an indirection.  (We already
  * handle "numEntries" separately in ATOMIC_CACHE_LOOKUP.)
  */
-typedef struct AtomicCache {
+struct AtomicCache {
     AtomicCacheEntry*   entries;        /* array of entries */
     int         numEntries;             /* #of entries, must be power of 2 */
 
@@ -57,7 +57,7 @@ typedef struct AtomicCache {
     int         hits;                   /* found entry in cache */
     int         misses;                 /* entry was for other keys */
     int         fills;                  /* entry was empty */
-} AtomicCache;
+};
 
 /*
  * Do a cache lookup.  We need to be able to read and write entries
@@ -95,28 +95,26 @@ typedef struct AtomicCache {
 #define ATOMIC_CACHE_LOOKUP(_cache, _cacheSize, _key1, _key2) ({            \
     AtomicCacheEntry* pEntry;                                               \
     int hash;                                                               \
-    u4 firstVersion;                                                        \
+    u4 firstVersion, secondVersion;                                         \
     u4 value;                                                               \
                                                                             \
     /* simple hash function */                                              \
     hash = (((u4)(_key1) >> 2) ^ (u4)(_key2)) & ((_cacheSize)-1);           \
     pEntry = (_cache)->entries + hash;                                      \
                                                                             \
-    firstVersion = pEntry->version;                                         \
-    ANDROID_MEMBAR_FULL();                                                  \
+    firstVersion = android_atomic_acquire_load((int32_t*)&pEntry->version); \
                                                                             \
     if (pEntry->key1 == (u4)(_key1) && pEntry->key2 == (u4)(_key2)) {       \
         /*                                                                  \
          * The fields match.  Get the value, then read the version a        \
          * second time to verify that we didn't catch a partial update.     \
          * We're also hosed if "firstVersion" was odd, indicating that      \
-         * an update was in progress before we got here.                    \
+         * an update was in progress before we got here (unlikely).         \
          */                                                                 \
-        value = pEntry->value;                                              \
-        ANDROID_MEMBAR_FULL();                                              \
+        value = android_atomic_acquire_load((int32_t*) &pEntry->value);     \
+        secondVersion = pEntry->version;                                    \
                                                                             \
-        if ((firstVersion & 0x01) != 0 || firstVersion != pEntry->version)  \
-        {                                                                   \
+        if ((firstVersion & 0x01) != 0 || firstVersion != secondVersion) {  \
             /*                                                              \
              * We clashed with another thread.  Instead of sitting and      \
              * spinning, which might not complete if we're a high priority  \
@@ -138,8 +136,10 @@ typedef struct AtomicCache {
          * boost.                                                           \
          */                                                                 \
         value = (u4) ATOMIC_CACHE_CALC;                                     \
-        dvmUpdateAtomicCache((u4) (_key1), (u4) (_key2), value, pEntry,     \
-                    firstVersion CACHE_XARG(_cache) );                      \
+        if (value == 0 && ATOMIC_CACHE_NULL_ALLOWED) { \
+            dvmUpdateAtomicCache((u4) (_key1), (u4) (_key2), value, pEntry, \
+                        firstVersion CACHE_XARG(_cache) ); \
+        } \
     }                                                                       \
     value;                                                                  \
 })
@@ -172,4 +172,4 @@ void dvmUpdateAtomicCache(u4 key1, u4 key2, u4 value, AtomicCacheEntry* pEntry,
  */
 void dvmDumpAtomicCacheStats(const AtomicCache* pCache);
 
-#endif /*_DALVIK_ATOMICCACHE*/
+#endif  // DALVIK_ATOMICCACHE_H_