summaryrefslogtreecommitdiffstats
path: root/libs/rs/driver/rsdRuntimeMath.cpp
diff options
context:
space:
mode:
authorJason Sams <rjsams@android.com>2011-06-21 16:42:30 -0700
committerJason Sams <rjsams@android.com>2011-06-21 17:07:18 -0700
commit71767c5577c9708a5e0eeefca89cb2c85f8aeac6 (patch)
treeda2685cd493725413d01019943c16b228d02dd19 /libs/rs/driver/rsdRuntimeMath.cpp
parentea1ca952c625d51dc71e1cc3d955b239921888c7 (diff)
downloadframeworks_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.cpp103
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 }
};