1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2020 SAP SE. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 import java.util.concurrent.CyclicBarrier; 26 27 import static java.lang.System.currentTimeMillis; 28 29 public class MetaspaceTestManyArenasManyThreads extends MetaspaceTestWithThreads { 30 31 // Several threads allocate from a single arena. 32 // This mimicks several threads loading classes via the same class loader. 33 34 public MetaspaceTestManyArenasManyThreads(MetaspaceTestContext context, long testAllocationCeiling, int numThreads, int seconds) { 35 super(context, testAllocationCeiling, numThreads, seconds); 36 } 37 38 public void runTest() throws Exception { 39 40 long t_start = currentTimeMillis(); 41 long t_stop = t_start + (seconds * 1000); 42 43 CyclicBarrier gate = new CyclicBarrier(numThreads + 1); 44 45 final long ceilingPerThread = testAllocationCeiling / numThreads; 46 47 for (int i = 0; i < numThreads; i ++) { 48 // Create n test threads, each one with its own allocator/arena pair 49 MetaspaceTestArena arena = context.createArena(RandomHelper.fiftyfifty(), ceilingPerThread); 50 RandomAllocator allocator = new RandomAllocator(arena); 51 RandomAllocatorThread thread = new RandomAllocatorThread(gate, allocator, i); 52 threads[i] = thread; 53 thread.start(); 54 } 55 56 gate.await(); 57 58 // while test is running, skim the arenas and kill any arena which is saturated (has started getting an 59 // untoward number of allocation failures) 60 while (System.currentTimeMillis() < t_stop) { 61 62 // Wait a bit 63 Thread.sleep(200); 64 65 for (RandomAllocatorThread t: threads) { 66 if (t.allocator.arena.numAllocationFailures > 0) { 67 t.interrupt(); 68 t.join(); 69 context.destroyArena(t.allocator.arena); 70 71 // Create a new arena, allocator, then a new thread (note: do not pass in a start gate this time 72 // since we do not need to wait) and fire it up. 73 MetaspaceTestArena arena = context.createArena(RandomHelper.fiftyfifty(), ceilingPerThread); 74 RandomAllocator allocator = new RandomAllocator(arena); 75 RandomAllocatorThread t2 = new RandomAllocatorThread(null, allocator, t.id); 76 threads[t.id] = t2; 77 t2.start(); 78 } 79 } 80 81 } 82 83 // Stop all threads. 84 stopAllThreads(); 85 86 context.updateTotals(); 87 System.out.println(" ## Finished: " + context); 88 89 context.checkStatistics(); 90 91 // Destroy all arenas; then purge the space. 92 destroyArenasAndPurgeSpace(); 93 94 context.destroy(); 95 96 context.updateTotals(); 97 98 System.out.println("This took " + (System.currentTimeMillis() - t_start) + "ms"); 99 100 } 101 102 } 103