1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "jni_internal.h"
18
19 #include <pthread.h>
20
21 #include "common_runtime_test.h"
22 #include "java_vm_ext.h"
23 #include "runtime.h"
24
25 namespace art {
26
27 class JavaVmExtTest : public CommonRuntimeTest {
28 protected:
SetUp()29 virtual void SetUp() {
30 CommonRuntimeTest::SetUp();
31
32 vm_ = Runtime::Current()->GetJavaVM();
33 }
34
35
TearDown()36 virtual void TearDown() OVERRIDE {
37 CommonRuntimeTest::TearDown();
38 }
39
40 JavaVMExt* vm_;
41 };
42
TEST_F(JavaVmExtTest,JNI_GetDefaultJavaVMInitArgs)43 TEST_F(JavaVmExtTest, JNI_GetDefaultJavaVMInitArgs) {
44 jint err = JNI_GetDefaultJavaVMInitArgs(nullptr);
45 EXPECT_EQ(JNI_ERR, err);
46 }
47
TEST_F(JavaVmExtTest,JNI_GetCreatedJavaVMs)48 TEST_F(JavaVmExtTest, JNI_GetCreatedJavaVMs) {
49 JavaVM* vms_buf[1];
50 jsize num_vms;
51 jint ok = JNI_GetCreatedJavaVMs(vms_buf, arraysize(vms_buf), &num_vms);
52 EXPECT_EQ(JNI_OK, ok);
53 EXPECT_EQ(1, num_vms);
54 EXPECT_EQ(vms_buf[0], vm_);
55 }
56
57 static bool gSmallStack = false;
58 static bool gAsDaemon = false;
59
attach_current_thread_callback(void * arg ATTRIBUTE_UNUSED)60 static void* attach_current_thread_callback(void* arg ATTRIBUTE_UNUSED) {
61 JavaVM* vms_buf[1];
62 jsize num_vms;
63 JNIEnv* env;
64 jint ok = JNI_GetCreatedJavaVMs(vms_buf, arraysize(vms_buf), &num_vms);
65 EXPECT_EQ(JNI_OK, ok);
66 if (ok == JNI_OK) {
67 if (!gAsDaemon) {
68 ok = vms_buf[0]->AttachCurrentThread(&env, nullptr);
69 } else {
70 ok = vms_buf[0]->AttachCurrentThreadAsDaemon(&env, nullptr);
71 }
72 // TODO: Find a way to test with exact SMALL_STACK value, for which we would bail. The pthreads
73 // spec says that the stack size argument is a lower bound, and bionic currently gives us
74 // a chunk more on arm64.
75 if (!gSmallStack) {
76 EXPECT_EQ(JNI_OK, ok);
77 }
78 if (ok == JNI_OK) {
79 ok = vms_buf[0]->DetachCurrentThread();
80 EXPECT_EQ(JNI_OK, ok);
81 }
82 }
83 return nullptr;
84 }
85
TEST_F(JavaVmExtTest,AttachCurrentThread)86 TEST_F(JavaVmExtTest, AttachCurrentThread) {
87 pthread_t pthread;
88 const char* reason = __PRETTY_FUNCTION__;
89 gSmallStack = false;
90 gAsDaemon = false;
91 CHECK_PTHREAD_CALL(pthread_create, (&pthread, nullptr, attach_current_thread_callback,
92 nullptr), reason);
93 void* ret_val;
94 CHECK_PTHREAD_CALL(pthread_join, (pthread, &ret_val), reason);
95 EXPECT_EQ(ret_val, nullptr);
96 }
97
TEST_F(JavaVmExtTest,AttachCurrentThreadAsDaemon)98 TEST_F(JavaVmExtTest, AttachCurrentThreadAsDaemon) {
99 pthread_t pthread;
100 const char* reason = __PRETTY_FUNCTION__;
101 gSmallStack = false;
102 gAsDaemon = true;
103 CHECK_PTHREAD_CALL(pthread_create, (&pthread, nullptr, attach_current_thread_callback,
104 nullptr), reason);
105 void* ret_val;
106 CHECK_PTHREAD_CALL(pthread_join, (pthread, &ret_val), reason);
107 EXPECT_EQ(ret_val, nullptr);
108 }
109
TEST_F(JavaVmExtTest,AttachCurrentThread_SmallStack)110 TEST_F(JavaVmExtTest, AttachCurrentThread_SmallStack) {
111 pthread_t pthread;
112 pthread_attr_t attr;
113 const char* reason = __PRETTY_FUNCTION__;
114 gSmallStack = true;
115 gAsDaemon = false;
116 CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), reason);
117 CHECK_PTHREAD_CALL(pthread_attr_setstacksize, (&attr, PTHREAD_STACK_MIN), reason);
118 CHECK_PTHREAD_CALL(pthread_create, (&pthread, &attr, attach_current_thread_callback,
119 nullptr), reason);
120 CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), reason);
121 void* ret_val;
122 CHECK_PTHREAD_CALL(pthread_join, (pthread, &ret_val), reason);
123 EXPECT_EQ(ret_val, nullptr);
124 }
125
TEST_F(JavaVmExtTest,DetachCurrentThread)126 TEST_F(JavaVmExtTest, DetachCurrentThread) {
127 JNIEnv* env;
128 jint ok = vm_->AttachCurrentThread(&env, nullptr);
129 ASSERT_EQ(JNI_OK, ok);
130 ok = vm_->DetachCurrentThread();
131 EXPECT_EQ(JNI_OK, ok);
132
133 jint err = vm_->DetachCurrentThread();
134 EXPECT_EQ(JNI_ERR, err);
135 }
136
137 } // namespace art
138