Home | History | Annotate | Download | only in art
      1 /*
      2  * Copyright (C) 2016 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 package art;
     18 
     19 import java.lang.ref.WeakReference;
     20 import java.util.ArrayList;
     21 import java.util.Arrays;
     22 import java.util.concurrent.CountDownLatch;
     23 import java.util.concurrent.Semaphore;
     24 
     25 public class Test1909 {
     26 
     27   public static class ThreadHolder {
     28     public Thread thr;
     29     public ThreadHolder(Thread thr) {
     30       this.thr = thr;
     31     }
     32 
     33     public long getTLS(long jvmtienv) {
     34       return Test1909.getTLS(jvmtienv, this.thr);
     35     }
     36     public void setTLS(long jvmtienv, long ptr) {
     37       Test1909.setTLS(jvmtienv, this.thr, ptr);
     38     }
     39   }
     40 
     41   public static class ThreadWaiter {
     42     public boolean exit;
     43     public Thread thr;
     44     public final Object lock;
     45 
     46     public ThreadWaiter() {
     47       this.exit = false;
     48       this.lock = new Object();
     49       this.thr = new Thread(() -> {
     50         try {
     51           synchronized (lock) {
     52             while (!this.exit) {
     53               this.lock.wait();
     54             }
     55           }
     56         } catch (Exception e) {
     57           e.printStackTrace();
     58         }
     59       });
     60       // Kill threads if we exit.
     61       thr.setDaemon(true);
     62       thr.start();
     63     }
     64 
     65     public void cleanup() throws Exception {
     66       synchronized (lock) {
     67         exit = true;
     68         lock.notifyAll();
     69       }
     70       thr.join();
     71     }
     72     public long getTLS(long jvmtienv) {
     73       return Test1909.getTLS(jvmtienv, this.thr);
     74     }
     75     public void setTLS(long jvmtienv, long ptr) {
     76       Test1909.setTLS(jvmtienv, this.thr, ptr);
     77     }
     78   }
     79 
     80   public static void checkEq(long a, long b) {
     81     if (a != b) {
     82       throw new Error("Expected: " + a + " got: " + b);
     83     }
     84   }
     85 
     86   public static void run() throws Exception {
     87     ThreadHolder tc = new ThreadHolder(Thread.currentThread());
     88     ThreadWaiter t1 = new ThreadWaiter();
     89     long e1 = newJvmtiEnv();
     90     long e2 = newJvmtiEnv();
     91 
     92     // Everything should be 0
     93     checkEq(0, tc.getTLS(e1));
     94     checkEq(0, t1.getTLS(e1));
     95     checkEq(0, tc.getTLS(e2));
     96     checkEq(0, t1.getTLS(e2));
     97 
     98     // Set in one pair.
     99     tc.setTLS(e1, 1);
    100     checkEq(1, tc.getTLS(e1));
    101     checkEq(0, t1.getTLS(e1));
    102     checkEq(0, tc.getTLS(e2));
    103     checkEq(0, t1.getTLS(e2));
    104 
    105     // Set in another pair.
    106     t1.setTLS(e1, 2);
    107     checkEq(1, tc.getTLS(e1));
    108     checkEq(2, t1.getTLS(e1));
    109     checkEq(0, tc.getTLS(e2));
    110     checkEq(0, t1.getTLS(e2));
    111 
    112     // Set in third pair.
    113     tc.setTLS(e2, 3);
    114     checkEq(1, tc.getTLS(e1));
    115     checkEq(2, t1.getTLS(e1));
    116     checkEq(3, tc.getTLS(e2));
    117     checkEq(0, t1.getTLS(e2));
    118 
    119     // Set in fourth pair.
    120     t1.setTLS(e2, 4);
    121     checkEq(1, tc.getTLS(e1));
    122     checkEq(2, t1.getTLS(e1));
    123     checkEq(3, tc.getTLS(e2));
    124     checkEq(4, t1.getTLS(e2));
    125 
    126     // Create a new thread and make sure everything is 0.
    127     ThreadWaiter t2 = new ThreadWaiter();
    128     checkEq(1, tc.getTLS(e1));
    129     checkEq(2, t1.getTLS(e1));
    130     checkEq(0, t2.getTLS(e1));
    131     checkEq(3, tc.getTLS(e2));
    132     checkEq(4, t1.getTLS(e2));
    133     checkEq(0, t2.getTLS(e2));
    134 
    135     // Create a new jvmtienv and make sure everything is 0.
    136     long e3 = newJvmtiEnv();
    137     checkEq(1, tc.getTLS(e1));
    138     checkEq(2, t1.getTLS(e1));
    139     checkEq(0, t2.getTLS(e1));
    140     checkEq(3, tc.getTLS(e2));
    141     checkEq(4, t1.getTLS(e2));
    142     checkEq(0, t2.getTLS(e2));
    143     checkEq(0, tc.getTLS(e3));
    144     checkEq(0, t1.getTLS(e3));
    145     checkEq(0, t2.getTLS(e3));
    146 
    147     // Delete an env without data and make sure everything is still there.
    148     destroyJvmtiEnv(e3);
    149     checkEq(1, tc.getTLS(e1));
    150     checkEq(2, t1.getTLS(e1));
    151     checkEq(0, t2.getTLS(e1));
    152     checkEq(3, tc.getTLS(e2));
    153     checkEq(4, t1.getTLS(e2));
    154     checkEq(0, t2.getTLS(e2));
    155 
    156     // Delete an env with data and make sure everything is still there.
    157     destroyJvmtiEnv(e2);
    158     checkEq(1, tc.getTLS(e1));
    159     checkEq(2, t1.getTLS(e1));
    160     checkEq(0, t2.getTLS(e1));
    161 
    162     // Delete a thread. Make sure other thread still has data.
    163     t1.cleanup();
    164     checkEq(1, tc.getTLS(e1));
    165     checkEq(0, t2.getTLS(e1));
    166 
    167     t2.cleanup();
    168 
    169     System.out.println("Test passed");
    170   }
    171 
    172   public static native long getTLS(long jvmtienv, Thread thr);
    173   public static native void setTLS(long jvmtienv, Thread thr, long ptr);
    174   public static native long newJvmtiEnv();
    175   public static native void destroyJvmtiEnv(long jvmtienv);
    176 }
    177