]> source.dussan.org Git - aspectj.git/blob
da9b8c296482573875bbc2b3ca3a9406d395dc71
[aspectj.git] /
1 /* *******************************************************************
2  * Copyright (c) 2004 IBM
3  * All rights reserved.
4  * This program and the accompanying materials are made available
5  * under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     Andy Clement -     initial implementation
11  * ******************************************************************/
12
13 package org.aspectj.apache.bcel.classfile.tests;
14
15 import org.aspectj.apache.bcel.classfile.Code;
16 import org.aspectj.apache.bcel.classfile.JavaClass;
17 import org.aspectj.apache.bcel.classfile.LocalVariableTable;
18 import org.aspectj.apache.bcel.classfile.Method;
19 import org.aspectj.apache.bcel.classfile.tests.BcelTestCase;
20
21 import java.util.concurrent.CountDownLatch;
22 import java.util.concurrent.ExecutorService;
23 import java.util.concurrent.Executors;
24 import java.util.concurrent.Semaphore;
25 import java.util.concurrent.atomic.AtomicReference;
26
27
28 public class LocalVariableTableConcurrencyTest extends BcelTestCase {
29
30         private final int nThreads = Runtime.getRuntime().availableProcessors();
31
32         private final ExecutorService[] workers = new ExecutorService[nThreads];
33
34         private LocalVariableTable reference;
35
36         protected void setUp() throws Exception {
37                 super.setUp();
38                 for (int i = 0; i < nThreads; i++) workers[i] = Executors.newSingleThreadExecutor();
39
40                 JavaClass clazz = getClassFromJar("SimpleGenericsProgram");
41
42                 Method mainMethod = getMethod(clazz,"main");
43                 Code codeAttr = (Code) findAttribute("Code",mainMethod.getAttributes());
44
45                 reference =
46                                 (LocalVariableTable) findAttribute("LocalVariableTable",codeAttr.getAttributes());
47         }
48
49         private LocalVariableTable createReferenceCopy() {
50                 try {
51                         return (LocalVariableTable) reference.clone();
52                 } catch (CloneNotSupportedException e) {
53                         throw new RuntimeException("Faileed to clone LocalVariableTable", e);
54                 }
55         }
56
57         public void testLocalVariableTableAttributeConcurrency() throws RuntimeException, InterruptedException {
58                 final AtomicReference<RuntimeException> error = new AtomicReference<>();
59                 for (int i = 0; i < 100000; i++) {
60                         LocalVariableTable sharedInstance = createReferenceCopy();
61                         CountDownLatch preStart = new CountDownLatch(nThreads);
62                         Semaphore start = new Semaphore(0);
63                         CountDownLatch finish = new CountDownLatch(nThreads);
64
65                         for (int j = 0; j < nThreads; j++) {
66                                 final boolean needsDelay = j > 0;
67                                 workers[j].execute(() -> {
68                                         preStart.countDown();
69                                         start.acquireUninterruptibly();
70                                         // trying to trigger concurrent unpacking - one tread should enter unpack() when other is about to leave it
71                                         if (needsDelay) createReferenceCopy().getTableLength();
72                                         try {
73                                                 sharedInstance.getTableLength();
74                                         }
75                                         catch (RuntimeException ex) {
76                                                 error.compareAndSet(null, ex);
77                                         }
78                                         finish.countDown();
79                                 });
80                         }
81
82                         preStart.await();
83                         start.release(nThreads);
84                         finish.await();
85
86                         if (error.get() != null) throw error.get();
87                 }
88         }
89
90         protected void tearDown() throws Exception {
91                 for (int i = 0; i < nThreads; i++) if (workers[i] != null) workers[i].shutdownNow();
92                 super.tearDown();
93         }
94 }