media/omx-plugin/include/gb/cutils/atomic.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /*
michael@0 2 * Copyright (C) 2007 The Android Open Source Project
michael@0 3 *
michael@0 4 * Licensed under the Apache License, Version 2.0 (the "License");
michael@0 5 * you may not use this file except in compliance with the License.
michael@0 6 * You may obtain a copy of the License at
michael@0 7 *
michael@0 8 * http://www.apache.org/licenses/LICENSE-2.0
michael@0 9 *
michael@0 10 * Unless required by applicable law or agreed to in writing, software
michael@0 11 * distributed under the License is distributed on an "AS IS" BASIS,
michael@0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
michael@0 13 * See the License for the specific language governing permissions and
michael@0 14 * limitations under the License.
michael@0 15 */
michael@0 16
michael@0 17 #ifndef ANDROID_CUTILS_ATOMIC_H
michael@0 18 #define ANDROID_CUTILS_ATOMIC_H
michael@0 19
michael@0 20 #include <stdint.h>
michael@0 21 #include <sys/types.h>
michael@0 22
michael@0 23 #ifdef __cplusplus
michael@0 24 extern "C" {
michael@0 25 #endif
michael@0 26
michael@0 27 /*
michael@0 28 * A handful of basic atomic operations. The appropriate pthread
michael@0 29 * functions should be used instead of these whenever possible.
michael@0 30 *
michael@0 31 * The "acquire" and "release" terms can be defined intuitively in terms
michael@0 32 * of the placement of memory barriers in a simple lock implementation:
michael@0 33 * - wait until compare-and-swap(lock-is-free --> lock-is-held) succeeds
michael@0 34 * - barrier
michael@0 35 * - [do work]
michael@0 36 * - barrier
michael@0 37 * - store(lock-is-free)
michael@0 38 * In very crude terms, the initial (acquire) barrier prevents any of the
michael@0 39 * "work" from happening before the lock is held, and the later (release)
michael@0 40 * barrier ensures that all of the work happens before the lock is released.
michael@0 41 * (Think of cached writes, cache read-ahead, and instruction reordering
michael@0 42 * around the CAS and store instructions.)
michael@0 43 *
michael@0 44 * The barriers must apply to both the compiler and the CPU. Note it is
michael@0 45 * legal for instructions that occur before an "acquire" barrier to be
michael@0 46 * moved down below it, and for instructions that occur after a "release"
michael@0 47 * barrier to be moved up above it.
michael@0 48 *
michael@0 49 * The ARM-driven implementation we use here is short on subtlety,
michael@0 50 * and actually requests a full barrier from the compiler and the CPU.
michael@0 51 * The only difference between acquire and release is in whether they
michael@0 52 * are issued before or after the atomic operation with which they
michael@0 53 * are associated. To ease the transition to C/C++ atomic intrinsics,
michael@0 54 * you should not rely on this, and instead assume that only the minimal
michael@0 55 * acquire/release protection is provided.
michael@0 56 *
michael@0 57 * NOTE: all int32_t* values are expected to be aligned on 32-bit boundaries.
michael@0 58 * If they are not, atomicity is not guaranteed.
michael@0 59 */
michael@0 60
michael@0 61 /*
michael@0 62 * Basic arithmetic and bitwise operations. These all provide a
michael@0 63 * barrier with "release" ordering, and return the previous value.
michael@0 64 *
michael@0 65 * These have the same characteristics (e.g. what happens on overflow)
michael@0 66 * as the equivalent non-atomic C operations.
michael@0 67 */
michael@0 68 int32_t android_atomic_inc(volatile int32_t* addr);
michael@0 69 int32_t android_atomic_dec(volatile int32_t* addr);
michael@0 70 int32_t android_atomic_add(int32_t value, volatile int32_t* addr);
michael@0 71 int32_t android_atomic_and(int32_t value, volatile int32_t* addr);
michael@0 72 int32_t android_atomic_or(int32_t value, volatile int32_t* addr);
michael@0 73
michael@0 74 /*
michael@0 75 * Perform an atomic load with "acquire" or "release" ordering.
michael@0 76 *
michael@0 77 * This is only necessary if you need the memory barrier. A 32-bit read
michael@0 78 * from a 32-bit aligned address is atomic on all supported platforms.
michael@0 79 */
michael@0 80 int32_t android_atomic_acquire_load(volatile const int32_t* addr);
michael@0 81 int32_t android_atomic_release_load(volatile const int32_t* addr);
michael@0 82
michael@0 83 /*
michael@0 84 * Perform an atomic store with "acquire" or "release" ordering.
michael@0 85 *
michael@0 86 * This is only necessary if you need the memory barrier. A 32-bit write
michael@0 87 * to a 32-bit aligned address is atomic on all supported platforms.
michael@0 88 */
michael@0 89 void android_atomic_acquire_store(int32_t value, volatile int32_t* addr);
michael@0 90 void android_atomic_release_store(int32_t value, volatile int32_t* addr);
michael@0 91
michael@0 92 /*
michael@0 93 * Unconditional swap operation with release ordering.
michael@0 94 *
michael@0 95 * Stores the new value at *addr, and returns the previous value.
michael@0 96 */
michael@0 97 int32_t android_atomic_swap(int32_t value, volatile int32_t* addr);
michael@0 98
michael@0 99 /*
michael@0 100 * Compare-and-set operation with "acquire" or "release" ordering.
michael@0 101 *
michael@0 102 * This returns zero if the new value was successfully stored, which will
michael@0 103 * only happen when *addr == oldvalue.
michael@0 104 *
michael@0 105 * (The return value is inverted from implementations on other platforms,
michael@0 106 * but matches the ARM ldrex/strex result.)
michael@0 107 *
michael@0 108 * Implementations that use the release CAS in a loop may be less efficient
michael@0 109 * than possible, because we re-issue the memory barrier on each iteration.
michael@0 110 */
michael@0 111 int android_atomic_acquire_cas(int32_t oldvalue, int32_t newvalue,
michael@0 112 volatile int32_t* addr);
michael@0 113 int android_atomic_release_cas(int32_t oldvalue, int32_t newvalue,
michael@0 114 volatile int32_t* addr);
michael@0 115
michael@0 116 /*
michael@0 117 * Aliases for code using an older version of this header. These are now
michael@0 118 * deprecated and should not be used. The definitions will be removed
michael@0 119 * in a future release.
michael@0 120 */
michael@0 121 #define android_atomic_write android_atomic_release_store
michael@0 122 #define android_atomic_cmpxchg android_atomic_release_cas
michael@0 123
michael@0 124 #ifdef __cplusplus
michael@0 125 } // extern "C"
michael@0 126 #endif
michael@0 127
michael@0 128 #endif // ANDROID_CUTILS_ATOMIC_H

mercurial