ART: Add three Timer functions
Add support for GetAvailableProcessors, GetTimerInfo and GetTime.
Add tests.
Bug: 31455788
Test: m test-art-host-run-test-926-timers
Change-Id: I9629654349787e27dee686284567b5de70e138f2
diff --git a/test/927-timers/build b/test/927-timers/build
new file mode 100755
index 0000000..898e2e5
--- /dev/null
+++ b/test/927-timers/build
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+./default-build "$@" --experimental agents
diff --git a/test/927-timers/expected.txt b/test/927-timers/expected.txt
new file mode 100644
index 0000000..a4ef442
--- /dev/null
+++ b/test/927-timers/expected.txt
@@ -0,0 +1,3 @@
+availableProcessors OK
+[-1, true, true, 32]
+Time OK
diff --git a/test/927-timers/info.txt b/test/927-timers/info.txt
new file mode 100644
index 0000000..875a5f6
--- /dev/null
+++ b/test/927-timers/info.txt
@@ -0,0 +1 @@
+Tests basic functions in the jvmti plugin.
diff --git a/test/927-timers/run b/test/927-timers/run
new file mode 100755
index 0000000..4379349
--- /dev/null
+++ b/test/927-timers/run
@@ -0,0 +1,19 @@
+#!/bin/bash
+#
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+./default-run "$@" --experimental agents \
+ --experimental runtime-plugins \
+ --jvmti
diff --git a/test/927-timers/src/Main.java b/test/927-timers/src/Main.java
new file mode 100644
index 0000000..2f5c85c
--- /dev/null
+++ b/test/927-timers/src/Main.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Arrays;
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[1]);
+
+ doTest();
+ }
+
+ private static void doTest() {
+ int all1 = Runtime.getRuntime().availableProcessors();
+ int all2 = getAvailableProcessors();
+ if (all1 != all2) {
+ throw new RuntimeException("Available processors doesn't match: " + all1 + " vs " + all2);
+ }
+ System.out.println("availableProcessors OK");
+
+ Object info[] = getTimerInfo();
+ System.out.println(Arrays.toString(info));
+
+ // getTime checks.
+ // Note: there isn't really much to check independent from the implementation. So we check
+ // a few details of the ART implementation. This may fail on other runtimes.
+ long time1 = getTime();
+ long time2 = getTime();
+
+ // Under normal circumstances, time1 <= time2.
+ if (time2 < time1) {
+ throw new RuntimeException("Time unexpectedly decreased: " + time1 + " vs " + time2);
+ }
+
+ long time3 = System.nanoTime();
+ long time4 = getTime();
+
+ final long MINUTE = 60l * 1000 * 1000 * 1000;
+ if (time4 < time3 || (time4 - time3 > MINUTE)) {
+ throw new RuntimeException("Time unexpectedly divergent: " + time3 + " vs " + time4);
+ }
+
+ System.out.println("Time OK");
+ }
+
+ private static native int getAvailableProcessors();
+ private static native Object[] getTimerInfo();
+ private static native long getTime();
+}
diff --git a/test/927-timers/timers.cc b/test/927-timers/timers.cc
new file mode 100644
index 0000000..58d5c27
--- /dev/null
+++ b/test/927-timers/timers.cc
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <inttypes.h>
+
+#include "android-base/stringprintf.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "jni.h"
+#include "openjdkjvmti/jvmti.h"
+
+#include "ti-agent/common_helper.h"
+#include "ti-agent/common_load.h"
+
+namespace art {
+namespace Test926Timers {
+
+extern "C" JNIEXPORT jint JNICALL Java_Main_getAvailableProcessors(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED) {
+ jint count;
+ jvmtiError result = jvmti_env->GetAvailableProcessors(&count);
+ if (JvmtiErrorToException(env, result)) {
+ return -1;
+ }
+ return count;
+}
+
+extern "C" JNIEXPORT jlong JNICALL Java_Main_getTime(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED) {
+ jlong time;
+ jvmtiError result = jvmti_env->GetTime(&time);
+ if (JvmtiErrorToException(env, result)) {
+ return -1;
+ }
+ return time;
+}
+
+extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getTimerInfo(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED) {
+ jvmtiTimerInfo info;
+ jvmtiError result = jvmti_env->GetTimerInfo(&info);
+ if (JvmtiErrorToException(env, result)) {
+ return nullptr;
+ }
+
+ auto callback = [&](jint index) -> jobject {
+ switch (index) {
+ // Max value.
+ case 0:
+ return env->NewStringUTF(android::base::StringPrintf("%" PRId64, info.max_value).c_str());
+
+ // Skip forward.
+ case 1:
+ return env->NewStringUTF(info.may_skip_forward == JNI_TRUE ? "true" : "false");
+ // Skip backward.
+ case 2:
+ return env->NewStringUTF(info.may_skip_forward == JNI_TRUE ? "true" : "false");
+
+ // The kind.
+ case 3:
+ return env->NewStringUTF(
+ android::base::StringPrintf("%d", static_cast<jint>(info.kind)).c_str());
+ }
+ LOG(FATAL) << "Should not reach here";
+ UNREACHABLE();
+ };
+ return CreateObjectArray(env, 4, "java/lang/Object", callback);
+}
+
+} // namespace Test926Timers
+} // namespace art
diff --git a/test/Android.bp b/test/Android.bp
index b0f0e5a..1ea1252 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -265,6 +265,7 @@
"922-properties/properties.cc",
"923-monitors/monitors.cc",
"924-threads/threads.cc",
+ "927-timers/timers.cc",
],
shared_libs: [
"libbase",
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 6068876..55cef97 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -304,6 +304,7 @@
923-monitors \
924-threads \
926-multi-obsolescence \
+ 927-timers \
ifneq (,$(filter target,$(TARGET_TYPES)))
ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES), \