Loading libs/rs/driver/rsdRuntimeMath.cpp +103 −0 Original line number Diff line number Diff line Loading @@ -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 ////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -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 } }; Loading libs/rs/scriptc/rs_math.rsh +222 −0 Original line number Diff line number Diff line Loading @@ -258,4 +258,226 @@ extern void __attribute__((overloadable)) rs_allocation output, const void * usrData, const rs_script_call_t *); /** * Atomic add one to the value at addr. * Equal to rsAtomicAdd(addr, 1) * * @param addr Address of value to increment * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicInc(volatile int32_t* addr); /** * Atomic add one to the value at addr. * Equal to rsAtomicAdd(addr, 1) * * @param addr Address of value to increment * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicInc(volatile uint32_t* addr); /** * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1) * * @param addr Address of value to decrement * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicDec(volatile int32_t* addr); /** * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1) * * @param addr Address of value to decrement * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicDec(volatile uint32_t* addr); /** * Atomic add a value to the value at addr. addr[0] += value * * @param addr Address of value to modify * @param value Amount to add to the value at addr * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicAdd(volatile int32_t* addr, int32_t value); /** * Atomic add a value to the value at addr. addr[0] += value * * @param addr Address of value to modify * @param value Amount to add to the value at addr * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicAdd(volatile uint32_t* addr, uint32_t value); /** * Atomic Subtract a value from the value at addr. addr[0] -= value * * @param addr Address of value to modify * @param value Amount to subtract from the value at addr * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicSub(volatile int32_t* addr, int32_t value); /** * Atomic Subtract a value from the value at addr. addr[0] -= value * * @param addr Address of value to modify * @param value Amount to subtract from the value at addr * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicSub(volatile uint32_t* addr, uint32_t value); /** * Atomic Bitwise and a value from the value at addr. addr[0] &= value * * @param addr Address of value to modify * @param value Amount to and with the value at addr * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicAnd(volatile int32_t* addr, int32_t value); /** * Atomic Bitwise and a value from the value at addr. addr[0] &= value * * @param addr Address of value to modify * @param value Amount to and with the value at addr * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicAnd(volatile uint32_t* addr, uint32_t value); /** * Atomic Bitwise or a value from the value at addr. addr[0] |= value * * @param addr Address of value to modify * @param value Amount to or with the value at addr * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicOr(volatile int32_t* addr, int32_t value); /** * Atomic Bitwise or a value from the value at addr. addr[0] |= value * * @param addr Address of value to modify * @param value Amount to or with the value at addr * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicOr(volatile uint32_t* addr, uint32_t value); /** * Atomic Bitwise xor a value from the value at addr. addr[0] ^= value * * @param addr Address of value to modify * @param value Amount to xor with the value at addr * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicXor(volatile uint32_t* addr, uint32_t value); /** * Atomic Bitwise xor a value from the value at addr. addr[0] ^= value * * @param addr Address of value to modify * @param value Amount to xor with the value at addr * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicXor(volatile int32_t* addr, int32_t value); /** * Atomic Set the value at addr to the min of addr and value * addr[0] = rsMin(addr[0], value) * * @param addr Address of value to modify * @param value comparison value * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicMin(volatile uint32_t* addr, uint32_t value); /** * Atomic Set the value at addr to the min of addr and value * addr[0] = rsMin(addr[0], value) * * @param addr Address of value to modify * @param value comparison value * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicMin(volatile int32_t* addr, int32_t value); /** * Atomic Set the value at addr to the max of addr and value * addr[0] = rsMax(addr[0], value) * * @param addr Address of value to modify * @param value comparison value * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicMax(volatile uint32_t* addr, uint32_t value); /** * Atomic Set the value at addr to the max of addr and value * addr[0] = rsMin(addr[0], value) * * @param addr Address of value to modify * @param value comparison value * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicMax(volatile int32_t* addr, int32_t value); /** * Compare-and-set operation with a full memory barrier. * * If the value at addr matches compareValue then newValue is written. * * @param addr The address to compare and replace if the compare passes. * @param compareValue The value to test addr[0] against. * @param newValue The value to write if the test passes. * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicCas(volatile int32_t* addr, int32_t compareValue, int32_t newValue); /** * Compare-and-set operation with a full memory barrier. * * If the value at addr matches compareValue then newValue is written. * * @param addr The address to compare and replace if the compare passes. * @param compareValue The value to test addr[0] against. * @param newValue The value to write if the test passes. * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicCas(volatile uint32_t* addr, int32_t compareValue, int32_t newValue); #endif Loading
libs/rs/driver/rsdRuntimeMath.cpp +103 −0 Original line number Diff line number Diff line Loading @@ -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 ////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -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 } }; Loading
libs/rs/scriptc/rs_math.rsh +222 −0 Original line number Diff line number Diff line Loading @@ -258,4 +258,226 @@ extern void __attribute__((overloadable)) rs_allocation output, const void * usrData, const rs_script_call_t *); /** * Atomic add one to the value at addr. * Equal to rsAtomicAdd(addr, 1) * * @param addr Address of value to increment * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicInc(volatile int32_t* addr); /** * Atomic add one to the value at addr. * Equal to rsAtomicAdd(addr, 1) * * @param addr Address of value to increment * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicInc(volatile uint32_t* addr); /** * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1) * * @param addr Address of value to decrement * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicDec(volatile int32_t* addr); /** * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1) * * @param addr Address of value to decrement * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicDec(volatile uint32_t* addr); /** * Atomic add a value to the value at addr. addr[0] += value * * @param addr Address of value to modify * @param value Amount to add to the value at addr * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicAdd(volatile int32_t* addr, int32_t value); /** * Atomic add a value to the value at addr. addr[0] += value * * @param addr Address of value to modify * @param value Amount to add to the value at addr * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicAdd(volatile uint32_t* addr, uint32_t value); /** * Atomic Subtract a value from the value at addr. addr[0] -= value * * @param addr Address of value to modify * @param value Amount to subtract from the value at addr * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicSub(volatile int32_t* addr, int32_t value); /** * Atomic Subtract a value from the value at addr. addr[0] -= value * * @param addr Address of value to modify * @param value Amount to subtract from the value at addr * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicSub(volatile uint32_t* addr, uint32_t value); /** * Atomic Bitwise and a value from the value at addr. addr[0] &= value * * @param addr Address of value to modify * @param value Amount to and with the value at addr * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicAnd(volatile int32_t* addr, int32_t value); /** * Atomic Bitwise and a value from the value at addr. addr[0] &= value * * @param addr Address of value to modify * @param value Amount to and with the value at addr * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicAnd(volatile uint32_t* addr, uint32_t value); /** * Atomic Bitwise or a value from the value at addr. addr[0] |= value * * @param addr Address of value to modify * @param value Amount to or with the value at addr * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicOr(volatile int32_t* addr, int32_t value); /** * Atomic Bitwise or a value from the value at addr. addr[0] |= value * * @param addr Address of value to modify * @param value Amount to or with the value at addr * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicOr(volatile uint32_t* addr, uint32_t value); /** * Atomic Bitwise xor a value from the value at addr. addr[0] ^= value * * @param addr Address of value to modify * @param value Amount to xor with the value at addr * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicXor(volatile uint32_t* addr, uint32_t value); /** * Atomic Bitwise xor a value from the value at addr. addr[0] ^= value * * @param addr Address of value to modify * @param value Amount to xor with the value at addr * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicXor(volatile int32_t* addr, int32_t value); /** * Atomic Set the value at addr to the min of addr and value * addr[0] = rsMin(addr[0], value) * * @param addr Address of value to modify * @param value comparison value * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicMin(volatile uint32_t* addr, uint32_t value); /** * Atomic Set the value at addr to the min of addr and value * addr[0] = rsMin(addr[0], value) * * @param addr Address of value to modify * @param value comparison value * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicMin(volatile int32_t* addr, int32_t value); /** * Atomic Set the value at addr to the max of addr and value * addr[0] = rsMax(addr[0], value) * * @param addr Address of value to modify * @param value comparison value * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicMax(volatile uint32_t* addr, uint32_t value); /** * Atomic Set the value at addr to the max of addr and value * addr[0] = rsMin(addr[0], value) * * @param addr Address of value to modify * @param value comparison value * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicMax(volatile int32_t* addr, int32_t value); /** * Compare-and-set operation with a full memory barrier. * * If the value at addr matches compareValue then newValue is written. * * @param addr The address to compare and replace if the compare passes. * @param compareValue The value to test addr[0] against. * @param newValue The value to write if the test passes. * * @return old value */ extern int32_t __attribute__((overloadable)) rsAtomicCas(volatile int32_t* addr, int32_t compareValue, int32_t newValue); /** * Compare-and-set operation with a full memory barrier. * * If the value at addr matches compareValue then newValue is written. * * @param addr The address to compare and replace if the compare passes. * @param compareValue The value to test addr[0] against. * @param newValue The value to write if the test passes. * * @return old value */ extern uint32_t __attribute__((overloadable)) rsAtomicCas(volatile uint32_t* addr, int32_t compareValue, int32_t newValue); #endif