diff options
author | Jason Sams <rjsams@android.com> | 2011-06-21 16:42:30 -0700 |
---|---|---|
committer | Jason Sams <rjsams@android.com> | 2011-06-21 17:07:18 -0700 |
commit | 71767c5577c9708a5e0eeefca89cb2c85f8aeac6 (patch) | |
tree | da2685cd493725413d01019943c16b228d02dd19 /libs/rs/driver/rsdRuntimeMath.cpp | |
parent | ea1ca952c625d51dc71e1cc3d955b239921888c7 (diff) | |
download | frameworks_base-71767c5577c9708a5e0eeefca89cb2c85f8aeac6.zip frameworks_base-71767c5577c9708a5e0eeefca89cb2c85f8aeac6.tar.gz frameworks_base-71767c5577c9708a5e0eeefca89cb2c85f8aeac6.tar.bz2 |
First cut of atomics for renderscript.
Change-Id: Iefc0228d802e6f5348ae787553c9252fb90ba110
update atomic patch.
Change-Id: Idd0596439c092f570b6b226e9a9c7102ddffe88e
Diffstat (limited to 'libs/rs/driver/rsdRuntimeMath.cpp')
-rw-r--r-- | libs/rs/driver/rsdRuntimeMath.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/libs/rs/driver/rsdRuntimeMath.cpp b/libs/rs/driver/rsdRuntimeMath.cpp index acb990d..d29da7e 100644 --- a/libs/rs/driver/rsdRuntimeMath.cpp +++ b/libs/rs/driver/rsdRuntimeMath.cpp @@ -268,6 +268,87 @@ static float SC_frac(float v) { } +static int32_t SC_AtomicCas(volatile int32_t *ptr, int32_t expectedValue, int32_t newValue) { + int32_t prev; + + do { + int32_t ret = android_atomic_release_cas(expectedValue, newValue, ptr); + if (!ret) { + // The android cas return 0 if it wrote the value. This means the + // previous value was the expected value and we can return. + return expectedValue; + } + // We didn't write the value and need to load the "previous" value. + prev = *ptr; + + // A race condition exists where the expected value could appear after our cas failed + // above. In this case loop until we have a legit previous value or the + // write passes. + } while (prev == expectedValue); + return prev; +} + + +static int32_t SC_AtomicInc(volatile int32_t *ptr) { + return android_atomic_inc(ptr); +} + +static int32_t SC_AtomicDec(volatile int32_t *ptr) { + return android_atomic_dec(ptr); +} + +static int32_t SC_AtomicAdd(volatile int32_t *ptr, int32_t value) { + return android_atomic_add(value, ptr); +} + +static int32_t SC_AtomicSub(volatile int32_t *ptr, int32_t value) { + int32_t prev, status; + do { + prev = *ptr; + status = android_atomic_release_cas(prev, prev - value, ptr); + } while (__builtin_expect(status != 0, 0)); + return prev; +} + +static int32_t SC_AtomicAnd(volatile int32_t *ptr, int32_t value) { + return android_atomic_and(value, ptr); +} + +static int32_t SC_AtomicOr(volatile int32_t *ptr, int32_t value) { + return android_atomic_or(value, ptr); +} + +static int32_t SC_AtomicXor(volatile int32_t *ptr, int32_t value) { + int32_t prev, status; + do { + prev = *ptr; + status = android_atomic_release_cas(prev, prev ^ value, ptr); + } while (__builtin_expect(status != 0, 0)); + return prev; +} + +static int32_t SC_AtomicMin(volatile int32_t *ptr, int32_t value) { + int32_t prev, status; + do { + prev = *ptr; + int32_t n = rsMin(value, prev); + status = android_atomic_release_cas(prev, n, ptr); + } while (__builtin_expect(status != 0, 0)); + return prev; +} + +static int32_t SC_AtomicMax(volatile int32_t *ptr, int32_t value) { + int32_t prev, status; + do { + prev = *ptr; + int32_t n = rsMax(value, prev); + status = android_atomic_release_cas(prev, n, ptr); + } while (__builtin_expect(status != 0, 0)); + return prev; +} + + + ////////////////////////////////////////////////////////////////////////////// // Class implementation ////////////////////////////////////////////////////////////////////////////// @@ -425,6 +506,28 @@ static RsdSymbolTable gSyms[] = { { "_Z6rsRandff", (void *)&SC_randf2, true }, { "_Z6rsFracf", (void *)&SC_frac, true }, + // Atomics + { "_Z11rsAtomicIncPVi", (void *)&SC_AtomicInc, true }, + { "_Z11rsAtomicIncPVj", (void *)&SC_AtomicInc, true }, + { "_Z11rsAtomicDecPVi", (void *)&SC_AtomicDec, true }, + { "_Z11rsAtomicDecPVj", (void *)&SC_AtomicDec, true }, + { "_Z11rsAtomicAddPVii", (void *)&SC_AtomicAdd, true }, + { "_Z11rsAtomicAddPVjj", (void *)&SC_AtomicAdd, true }, + { "_Z11rsAtomicSubPVii", (void *)&SC_AtomicSub, true }, + { "_Z11rsAtomicSubPVjj", (void *)&SC_AtomicSub, true }, + { "_Z11rsAtomicAndPVii", (void *)&SC_AtomicAnd, true }, + { "_Z11rsAtomicAndPVjj", (void *)&SC_AtomicAnd, true }, + { "_Z10rsAtomicOrPVii", (void *)&SC_AtomicOr, true }, + { "_Z10rsAtomicOrPVjj", (void *)&SC_AtomicOr, true }, + { "_Z11rsAtomicXorPVii", (void *)&SC_AtomicXor, true }, + { "_Z11rsAtomicXorPVjj", (void *)&SC_AtomicXor, true }, + { "_Z11rsAtomicMinPVii", (void *)&SC_AtomicMin, true }, + { "_Z11rsAtomicMinPVjj", (void *)&SC_AtomicMin, true }, + { "_Z11rsAtomicMaxPVii", (void *)&SC_AtomicMax, true }, + { "_Z11rsAtomicMaxPVjj", (void *)&SC_AtomicMax, true }, + { "_Z11rsAtomicCasPViii", (void *)&SC_AtomicCas, true }, + { "_Z11rsAtomicCasPVjjj", (void *)&SC_AtomicCas, true }, + { NULL, NULL, false } }; |