| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package art; |
| |
| import java.lang.ref.WeakReference; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.Semaphore; |
| |
| public class Test1909 { |
| |
| public static class ThreadHolder { |
| public Thread thr; |
| public ThreadHolder(Thread thr) { |
| this.thr = thr; |
| } |
| |
| public long getTLS(long jvmtienv) { |
| return Test1909.getTLS(jvmtienv, this.thr); |
| } |
| public void setTLS(long jvmtienv, long ptr) { |
| Test1909.setTLS(jvmtienv, this.thr, ptr); |
| } |
| } |
| |
| public static class ThreadWaiter { |
| public boolean exit; |
| public Thread thr; |
| public final Object lock; |
| |
| public ThreadWaiter() { |
| this.exit = false; |
| this.lock = new Object(); |
| this.thr = new Thread(() -> { |
| try { |
| synchronized (lock) { |
| while (!this.exit) { |
| this.lock.wait(); |
| } |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| }); |
| // Kill threads if we exit. |
| thr.setDaemon(true); |
| thr.start(); |
| } |
| |
| public void cleanup() throws Exception { |
| synchronized (lock) { |
| exit = true; |
| lock.notifyAll(); |
| } |
| thr.join(); |
| } |
| public long getTLS(long jvmtienv) { |
| return Test1909.getTLS(jvmtienv, this.thr); |
| } |
| public void setTLS(long jvmtienv, long ptr) { |
| Test1909.setTLS(jvmtienv, this.thr, ptr); |
| } |
| } |
| |
| public static void checkEq(long a, long b) { |
| if (a != b) { |
| throw new Error("Expected: " + a + " got: " + b); |
| } |
| } |
| |
| public static void run() throws Exception { |
| ThreadHolder tc = new ThreadHolder(Thread.currentThread()); |
| ThreadWaiter t1 = new ThreadWaiter(); |
| long e1 = newJvmtiEnv(); |
| long e2 = newJvmtiEnv(); |
| |
| // Everything should be 0 |
| checkEq(0, tc.getTLS(e1)); |
| checkEq(0, t1.getTLS(e1)); |
| checkEq(0, tc.getTLS(e2)); |
| checkEq(0, t1.getTLS(e2)); |
| |
| // Set in one pair. |
| tc.setTLS(e1, 1); |
| checkEq(1, tc.getTLS(e1)); |
| checkEq(0, t1.getTLS(e1)); |
| checkEq(0, tc.getTLS(e2)); |
| checkEq(0, t1.getTLS(e2)); |
| |
| // Set in another pair. |
| t1.setTLS(e1, 2); |
| checkEq(1, tc.getTLS(e1)); |
| checkEq(2, t1.getTLS(e1)); |
| checkEq(0, tc.getTLS(e2)); |
| checkEq(0, t1.getTLS(e2)); |
| |
| // Set in third pair. |
| tc.setTLS(e2, 3); |
| checkEq(1, tc.getTLS(e1)); |
| checkEq(2, t1.getTLS(e1)); |
| checkEq(3, tc.getTLS(e2)); |
| checkEq(0, t1.getTLS(e2)); |
| |
| // Set in fourth pair. |
| t1.setTLS(e2, 4); |
| checkEq(1, tc.getTLS(e1)); |
| checkEq(2, t1.getTLS(e1)); |
| checkEq(3, tc.getTLS(e2)); |
| checkEq(4, t1.getTLS(e2)); |
| |
| // Create a new thread and make sure everything is 0. |
| ThreadWaiter t2 = new ThreadWaiter(); |
| checkEq(1, tc.getTLS(e1)); |
| checkEq(2, t1.getTLS(e1)); |
| checkEq(0, t2.getTLS(e1)); |
| checkEq(3, tc.getTLS(e2)); |
| checkEq(4, t1.getTLS(e2)); |
| checkEq(0, t2.getTLS(e2)); |
| |
| // Create a new jvmtienv and make sure everything is 0. |
| long e3 = newJvmtiEnv(); |
| checkEq(1, tc.getTLS(e1)); |
| checkEq(2, t1.getTLS(e1)); |
| checkEq(0, t2.getTLS(e1)); |
| checkEq(3, tc.getTLS(e2)); |
| checkEq(4, t1.getTLS(e2)); |
| checkEq(0, t2.getTLS(e2)); |
| checkEq(0, tc.getTLS(e3)); |
| checkEq(0, t1.getTLS(e3)); |
| checkEq(0, t2.getTLS(e3)); |
| |
| // Delete an env without data and make sure everything is still there. |
| destroyJvmtiEnv(e3); |
| checkEq(1, tc.getTLS(e1)); |
| checkEq(2, t1.getTLS(e1)); |
| checkEq(0, t2.getTLS(e1)); |
| checkEq(3, tc.getTLS(e2)); |
| checkEq(4, t1.getTLS(e2)); |
| checkEq(0, t2.getTLS(e2)); |
| |
| // Delete an env with data and make sure everything is still there. |
| destroyJvmtiEnv(e2); |
| checkEq(1, tc.getTLS(e1)); |
| checkEq(2, t1.getTLS(e1)); |
| checkEq(0, t2.getTLS(e1)); |
| |
| // Delete a thread. Make sure other thread still has data. |
| t1.cleanup(); |
| checkEq(1, tc.getTLS(e1)); |
| checkEq(0, t2.getTLS(e1)); |
| |
| t2.cleanup(); |
| |
| System.out.println("Test passed"); |
| } |
| |
| public static native long getTLS(long jvmtienv, Thread thr); |
| public static native void setTLS(long jvmtienv, Thread thr, long ptr); |
| public static native long newJvmtiEnv(); |
| public static native void destroyJvmtiEnv(long jvmtienv); |
| } |