1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/omx-plugin/include/gb/cutils/atomic.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,128 @@ 1.4 +/* 1.5 + * Copyright (C) 2007 The Android Open Source Project 1.6 + * 1.7 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.8 + * you may not use this file except in compliance with the License. 1.9 + * You may obtain a copy of the License at 1.10 + * 1.11 + * http://www.apache.org/licenses/LICENSE-2.0 1.12 + * 1.13 + * Unless required by applicable law or agreed to in writing, software 1.14 + * distributed under the License is distributed on an "AS IS" BASIS, 1.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.16 + * See the License for the specific language governing permissions and 1.17 + * limitations under the License. 1.18 + */ 1.19 + 1.20 +#ifndef ANDROID_CUTILS_ATOMIC_H 1.21 +#define ANDROID_CUTILS_ATOMIC_H 1.22 + 1.23 +#include <stdint.h> 1.24 +#include <sys/types.h> 1.25 + 1.26 +#ifdef __cplusplus 1.27 +extern "C" { 1.28 +#endif 1.29 + 1.30 +/* 1.31 + * A handful of basic atomic operations. The appropriate pthread 1.32 + * functions should be used instead of these whenever possible. 1.33 + * 1.34 + * The "acquire" and "release" terms can be defined intuitively in terms 1.35 + * of the placement of memory barriers in a simple lock implementation: 1.36 + * - wait until compare-and-swap(lock-is-free --> lock-is-held) succeeds 1.37 + * - barrier 1.38 + * - [do work] 1.39 + * - barrier 1.40 + * - store(lock-is-free) 1.41 + * In very crude terms, the initial (acquire) barrier prevents any of the 1.42 + * "work" from happening before the lock is held, and the later (release) 1.43 + * barrier ensures that all of the work happens before the lock is released. 1.44 + * (Think of cached writes, cache read-ahead, and instruction reordering 1.45 + * around the CAS and store instructions.) 1.46 + * 1.47 + * The barriers must apply to both the compiler and the CPU. Note it is 1.48 + * legal for instructions that occur before an "acquire" barrier to be 1.49 + * moved down below it, and for instructions that occur after a "release" 1.50 + * barrier to be moved up above it. 1.51 + * 1.52 + * The ARM-driven implementation we use here is short on subtlety, 1.53 + * and actually requests a full barrier from the compiler and the CPU. 1.54 + * The only difference between acquire and release is in whether they 1.55 + * are issued before or after the atomic operation with which they 1.56 + * are associated. To ease the transition to C/C++ atomic intrinsics, 1.57 + * you should not rely on this, and instead assume that only the minimal 1.58 + * acquire/release protection is provided. 1.59 + * 1.60 + * NOTE: all int32_t* values are expected to be aligned on 32-bit boundaries. 1.61 + * If they are not, atomicity is not guaranteed. 1.62 + */ 1.63 + 1.64 +/* 1.65 + * Basic arithmetic and bitwise operations. These all provide a 1.66 + * barrier with "release" ordering, and return the previous value. 1.67 + * 1.68 + * These have the same characteristics (e.g. what happens on overflow) 1.69 + * as the equivalent non-atomic C operations. 1.70 + */ 1.71 +int32_t android_atomic_inc(volatile int32_t* addr); 1.72 +int32_t android_atomic_dec(volatile int32_t* addr); 1.73 +int32_t android_atomic_add(int32_t value, volatile int32_t* addr); 1.74 +int32_t android_atomic_and(int32_t value, volatile int32_t* addr); 1.75 +int32_t android_atomic_or(int32_t value, volatile int32_t* addr); 1.76 + 1.77 +/* 1.78 + * Perform an atomic load with "acquire" or "release" ordering. 1.79 + * 1.80 + * This is only necessary if you need the memory barrier. A 32-bit read 1.81 + * from a 32-bit aligned address is atomic on all supported platforms. 1.82 + */ 1.83 +int32_t android_atomic_acquire_load(volatile const int32_t* addr); 1.84 +int32_t android_atomic_release_load(volatile const int32_t* addr); 1.85 + 1.86 +/* 1.87 + * Perform an atomic store with "acquire" or "release" ordering. 1.88 + * 1.89 + * This is only necessary if you need the memory barrier. A 32-bit write 1.90 + * to a 32-bit aligned address is atomic on all supported platforms. 1.91 + */ 1.92 +void android_atomic_acquire_store(int32_t value, volatile int32_t* addr); 1.93 +void android_atomic_release_store(int32_t value, volatile int32_t* addr); 1.94 + 1.95 +/* 1.96 + * Unconditional swap operation with release ordering. 1.97 + * 1.98 + * Stores the new value at *addr, and returns the previous value. 1.99 + */ 1.100 +int32_t android_atomic_swap(int32_t value, volatile int32_t* addr); 1.101 + 1.102 +/* 1.103 + * Compare-and-set operation with "acquire" or "release" ordering. 1.104 + * 1.105 + * This returns zero if the new value was successfully stored, which will 1.106 + * only happen when *addr == oldvalue. 1.107 + * 1.108 + * (The return value is inverted from implementations on other platforms, 1.109 + * but matches the ARM ldrex/strex result.) 1.110 + * 1.111 + * Implementations that use the release CAS in a loop may be less efficient 1.112 + * than possible, because we re-issue the memory barrier on each iteration. 1.113 + */ 1.114 +int android_atomic_acquire_cas(int32_t oldvalue, int32_t newvalue, 1.115 + volatile int32_t* addr); 1.116 +int android_atomic_release_cas(int32_t oldvalue, int32_t newvalue, 1.117 + volatile int32_t* addr); 1.118 + 1.119 +/* 1.120 + * Aliases for code using an older version of this header. These are now 1.121 + * deprecated and should not be used. The definitions will be removed 1.122 + * in a future release. 1.123 + */ 1.124 +#define android_atomic_write android_atomic_release_store 1.125 +#define android_atomic_cmpxchg android_atomic_release_cas 1.126 + 1.127 +#ifdef __cplusplus 1.128 +} // extern "C" 1.129 +#endif 1.130 + 1.131 +#endif // ANDROID_CUTILS_ATOMIC_H