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