JNIEXPORT void JNICALL Java_com_google_example_games_tunnel_OurActivity_native_1ReportJoystickPresent (JNIEnv *env, jobject thiz, jboolean present) { LOGD("Joystick report: %s", present ? "PRESENT" : "ABSENT"); __atomic_swap(present ? 1 : 0, &_joystick_present); }
JNIEXPORT void JNICALL Java_com_google_example_games_tunnel_OurActivity_native_1ReportCloudLoadResult (JNIEnv *env, jobject thiz, jboolean success, jint level) { _cloud_load_success = (bool) success; _cloud_load_data = (int) level; __atomic_swap(1, &_cloud_result_available); LOGD("Cloud load result: %s, level %d", _cloud_load_success ? "SUCCESS" : "FAILURE", _cloud_load_data); }
/* * Start tests, show results. */ bool dvmTestAtomicSpeed() { pthread_t threads[THREAD_COUNT]; void *(*startRoutine)(void *) = atomicTest; int64_t startWhen, endWhen; #if defined(__ARM_ARCH__) dvmFprintf(stdout, "__ARM_ARCH__ is %d\n", __ARM_ARCH__); #endif #if defined(ANDROID_SMP) dvmFprintf(stdout, "ANDROID_SMP is %d\n", ANDROID_SMP); #endif dvmFprintf(stdout, "Creating threads\n"); int i; for (i = 0; i < THREAD_COUNT; i++) { void *arg = (void *) i; if (pthread_create(&threads[i], NULL, startRoutine, arg) != 0) { dvmFprintf(stderr, "thread create failed\n"); } } /* wait for all the threads to reach the starting line */ while (1) { pthread_mutex_lock(&waitLock); if (threadsStarted == THREAD_COUNT) { dvmFprintf(stdout, "Starting test\n"); startWhen = getRelativeTimeNsec(); pthread_cond_broadcast(&waitCond); pthread_mutex_unlock(&waitLock); break; } pthread_mutex_unlock(&waitLock); usleep(100000); } for (i = 0; i < THREAD_COUNT; i++) { void *retval; if (pthread_join(threads[i], &retval) != 0) { dvmFprintf(stderr, "thread join (%d) failed\n", i); } } endWhen = getRelativeTimeNsec(); dvmFprintf(stdout, "All threads stopped, time is %.6fms\n", (endWhen - startWhen) / 1000000.0); /* * Show results; expecting: * * incTest = 5000000 * decTest = -5000000 * addTest = 7500000 * casTest = 10000000 * wideCasTest = 0x6600000077000000 */ dvmFprintf(stdout, "incTest = %d\n", incTest); dvmFprintf(stdout, "decTest = %d\n", decTest); dvmFprintf(stdout, "addTest = %d\n", addTest); dvmFprintf(stdout, "casTest = %d\n", casTest); dvmFprintf(stdout, "wideCasTest = 0x%llx\n", wideCasTest); /* do again, serially (SMP check) */ startWhen = getRelativeTimeNsec(); for (i = 0; i < THREAD_COUNT; i++) { doAtomicTest(i); } endWhen = getRelativeTimeNsec(); dvmFprintf(stdout, "Same iterations done serially: time is %.6fms\n", (endWhen - startWhen) / 1000000.0); /* * Hard to do a meaningful thrash test on these, so just do a simple * function test. */ andTest = 0xffd7fa96; orTest = 0x122221ff; android_atomic_and(0xfffdaf96, &andTest); android_atomic_or(0xdeaaeb00, &orTest); if (android_atomic_release_cas(failingCasTest + 1, failingCasTest - 1, &failingCasTest) == 0) dvmFprintf(stdout, "failing test did not fail!\n"); dvmFprintf(stdout, "andTest = %#x\n", andTest); dvmFprintf(stdout, "orTest = %#x\n", orTest); dvmFprintf(stdout, "failingCasTest = %d\n", failingCasTest); #ifdef TEST_BIONIC /* * Quick function test on the bionic ops. */ int prev; int tester = 7; prev = __atomic_inc(&tester); __atomic_inc(&tester); __atomic_inc(&tester); dvmFprintf(stdout, "bionic 3 inc: %d -> %d\n", prev, tester); prev = __atomic_dec(&tester); __atomic_dec(&tester); __atomic_dec(&tester); dvmFprintf(stdout, "bionic 3 dec: %d -> %d\n", prev, tester); prev = __atomic_swap(27, &tester); dvmFprintf(stdout, "bionic swap: %d -> %d\n", prev, tester); int swapok = __atomic_cmpxchg(27, 72, &tester); dvmFprintf(stdout, "bionic cmpxchg: %d (%d)\n", tester, swapok); #endif testAtomicSpeed(); return 0; }