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; ThreadHolder(Thread thr)29 public ThreadHolder(Thread thr) { 30 this.thr = thr; 31 } 32 getTLS(long jvmtienv)33 public long getTLS(long jvmtienv) { 34 return Test1909.getTLS(jvmtienv, this.thr); 35 } setTLS(long jvmtienv, long ptr)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 ThreadWaiter()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 cleanup()65 public void cleanup() throws Exception { 66 synchronized (lock) { 67 exit = true; 68 lock.notifyAll(); 69 } 70 thr.join(); 71 } getTLS(long jvmtienv)72 public long getTLS(long jvmtienv) { 73 return Test1909.getTLS(jvmtienv, this.thr); 74 } setTLS(long jvmtienv, long ptr)75 public void setTLS(long jvmtienv, long ptr) { 76 Test1909.setTLS(jvmtienv, this.thr, ptr); 77 } 78 } 79 checkEq(long a, long b)80 public static void checkEq(long a, long b) { 81 if (a != b) { 82 throw new Error("Expected: " + a + " got: " + b); 83 } 84 } 85 run()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 getTLS(long jvmtienv, Thread thr)172 public static native long getTLS(long jvmtienv, Thread thr); setTLS(long jvmtienv, Thread thr, long ptr)173 public static native void setTLS(long jvmtienv, Thread thr, long ptr); newJvmtiEnv()174 public static native long newJvmtiEnv(); destroyJvmtiEnv(long jvmtienv)175 public static native void destroyJvmtiEnv(long jvmtienv); 176 } 177