summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2012-01-25 18:17:34 -0800
committerStephen Hines <srhines@google.com>2012-01-25 18:17:34 -0800
commitfa54999eb657180fe82b556c75761f37fed599dc (patch)
treed14b19c495f77cf972a0deb304bb90d862ec776a
parentb9dfecaf56642de220c7e5563ff306aa9a5412f9 (diff)
downloadrs-fa54999eb657180fe82b556c75761f37fed599dc.tar.gz
Fix bugs with unsigned rsAtomicCas/Max/Min.
BUG=5888007 rsAtomicMax/Min did not have proper semantics for unsigned integers. They were always using signed comparisons. rsAtomicCas had the wrong function signature in our math library, leading to no way to properly link/execute it. Change-Id: I336cdd8cd9f2d8093f12e101b55b2797515f039b
-rw-r--r--driver/rsdRuntimeMath.cpp24
-rw-r--r--scriptc/rs_atomic.rsh2
2 files changed, 23 insertions, 3 deletions
diff --git a/driver/rsdRuntimeMath.cpp b/driver/rsdRuntimeMath.cpp
index e3155396..753ef735 100644
--- a/driver/rsdRuntimeMath.cpp
+++ b/driver/rsdRuntimeMath.cpp
@@ -329,6 +329,16 @@ static int32_t SC_AtomicXor(volatile int32_t *ptr, int32_t value) {
return prev;
}
+static uint32_t SC_AtomicUMin(volatile uint32_t *ptr, uint32_t value) {
+ uint32_t prev, status;
+ do {
+ prev = *ptr;
+ uint32_t n = rsMin(value, prev);
+ status = android_atomic_release_cas((int32_t) prev, (int32_t)n, (volatile int32_t*) ptr);
+ } while (CC_UNLIKELY(status != 0));
+ return prev;
+}
+
static int32_t SC_AtomicMin(volatile int32_t *ptr, int32_t value) {
int32_t prev, status;
do {
@@ -339,6 +349,16 @@ static int32_t SC_AtomicMin(volatile int32_t *ptr, int32_t value) {
return prev;
}
+static uint32_t SC_AtomicUMax(volatile uint32_t *ptr, uint32_t value) {
+ uint32_t prev, status;
+ do {
+ prev = *ptr;
+ uint32_t n = rsMax(value, prev);
+ status = android_atomic_release_cas((int32_t) prev, (int32_t) n, (volatile int32_t*) ptr);
+ } while (CC_UNLIKELY(status != 0));
+ return prev;
+}
+
static int32_t SC_AtomicMax(volatile int32_t *ptr, int32_t value) {
int32_t prev, status;
do {
@@ -524,9 +544,9 @@ static RsdSymbolTable gSyms[] = {
{ "_Z11rsAtomicXorPVii", (void *)&SC_AtomicXor, true },
{ "_Z11rsAtomicXorPVjj", (void *)&SC_AtomicXor, true },
{ "_Z11rsAtomicMinPVii", (void *)&SC_AtomicMin, true },
- { "_Z11rsAtomicMinPVjj", (void *)&SC_AtomicMin, true },
+ { "_Z11rsAtomicMinPVjj", (void *)&SC_AtomicUMin, true },
{ "_Z11rsAtomicMaxPVii", (void *)&SC_AtomicMax, true },
- { "_Z11rsAtomicMaxPVjj", (void *)&SC_AtomicMax, true },
+ { "_Z11rsAtomicMaxPVjj", (void *)&SC_AtomicUMax, true },
{ "_Z11rsAtomicCasPViii", (void *)&SC_AtomicCas, true },
{ "_Z11rsAtomicCasPVjjj", (void *)&SC_AtomicCas, true },
diff --git a/scriptc/rs_atomic.rsh b/scriptc/rs_atomic.rsh
index 87c6c021..a455edd4 100644
--- a/scriptc/rs_atomic.rsh
+++ b/scriptc/rs_atomic.rsh
@@ -242,7 +242,7 @@ extern int32_t __attribute__((overloadable))
* @return old value
*/
extern uint32_t __attribute__((overloadable))
- rsAtomicCas(volatile uint32_t* addr, int32_t compareValue, int32_t newValue);
+ rsAtomicCas(volatile uint32_t* addr, uint32_t compareValue, uint32_t newValue);
#endif //defined(RS_VERSION) && (RS_VERSION >= 14)