Home | History | Annotate | Download | only in runtime
      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:
     29   virtual void SetUp() {
     30     CommonRuntimeTest::SetUp();
     31 
     32     vm_ = Runtime::Current()->GetJavaVM();
     33   }
     34 
     35 
     36   virtual void TearDown() OVERRIDE {
     37     CommonRuntimeTest::TearDown();
     38   }
     39 
     40   JavaVMExt* vm_;
     41 };
     42 
     43 TEST_F(JavaVmExtTest, JNI_GetDefaultJavaVMInitArgs) {
     44   jint err = JNI_GetDefaultJavaVMInitArgs(nullptr);
     45   EXPECT_EQ(JNI_ERR, err);
     46 }
     47 
     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 
     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 
     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 
     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 
    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 
    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