1 /*
   2  * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @key stress gc
  27  *
  28  * @summary converted from VM Testbase gc/gctests/MTLinkedListGC.
  29  * VM Testbase keywords: [gc, stress, nonconcurrent]
  30  * VM Testbase readme:
  31  * In this test 1000 threads contribute in the formation
  32  * of 1 Meg circular Linked list. Insertion into the linked list
  33  * is sequential. Once formed, the linked list is converted to
  34  * garbage and the process repeated 50 times. The test fails
  35  * if an OutofMemoryException is thrown and passes otherwise.
  36  *
  37  * @library /vmTestbase
  38  *          /test/lib
  39  * @run driver jdk.test.lib.FileInstaller . .
  40  * @run main/othervm gc.gctests.MTLinkedListGC.MTLinkedListGC
  41  */
  42 
  43 package gc.gctests.MTLinkedListGC;
  44 
  45 import java.util.Vector;
  46 import nsk.share.TestFailure;
  47 
  48 class CircularLinkedList {
  49         synchronized void addElement(String info) {
  50                 node newnode;
  51                 int elementCount ; // Number of nodes in LinkedList
  52                 elementCount = elementCount();
  53                 // Do not allow the linked list to grow to more
  54                 // than  100000 nodes
  55                 if (elementCount >= MAXNODES)
  56                          return;
  57                 newnode = new node(info);
  58                 if (Root == null) {
  59                          Root = newnode;
  60                          Root.next = Root;
  61                          Root.prev = Root;
  62                 }
  63                 else {
  64                          newnode.next = Root.next;
  65                          Root.next.prev = newnode;
  66                          Root.next = newnode;
  67                          newnode.prev = Root;
  68                 }
  69         }
  70         private synchronized int elementCount() {
  71                 node p;
  72                 int count;
  73                 if (Root == null)
  74                         return 0;
  75                 p = Root;
  76                 count = 0;
  77                 do {
  78                         p = p.prev;
  79                         count++;
  80                 } while(p != Root);
  81                 return count;
  82         }
  83         private node Root;
  84         private final int MAXNODES = 100000;
  85 }
  86 
  87 class LinkedListGrower extends Thread {
  88         LinkedListGrower(int ThreadNumber) {
  89                 setName("Thread-" + ThreadNumber);
  90         }
  91 
  92         public void run() {
  93                 LinkedListHolder.getCircularLinkedList().addElement(getName());
  94         }
  95 }
  96 
  97 class LinkedListHolder {
  98         private static CircularLinkedList cl = new CircularLinkedList();
  99         static CircularLinkedList getCircularLinkedList() { return cl; }
 100         static void getNewList() { cl = new CircularLinkedList(); }
 101 }
 102 
 103 public class MTLinkedListGC {
 104         public static void main(String args[]) {
 105                 int memory_reserve[] = new int [1000];
 106                 Thread ThreadsArray[] = new LinkedListGrower[1000];
 107                 int count;
 108 //              for(int i = 0; i < ThreadsArray.length; i++ )
 109 //                      ThreadsArray[i] = new LinkedListGrower(i);
 110                 count = 0;
 111                 try {
 112                         while(count < 50 ){
 113                                 for(int i = 0; i < ThreadsArray.length; i++ )
 114                                         ThreadsArray[i] = new LinkedListGrower(i);
 115                                 for(int i = 0 ; i < ThreadsArray.length ; i++)
 116                                         ThreadsArray[i].start();
 117                                 try {
 118                                         for(int i =0 ; i < ThreadsArray.length ; i++)
 119                                                 ThreadsArray[i].join();
 120                                 } catch(Exception e) { }
 121                                 //turn the old linked list into garbage
 122                                 LinkedListHolder.getNewList();
 123                                 System.out.println("Finished iteration " + count);
 124                                 count ++;
 125                         }
 126                 } catch (OutOfMemoryError e) {
 127                         memory_reserve = null;
 128                         System.gc();
 129                         throw new TestFailure("Test Failed at " + count +"th iteration.");
 130                 }
 131                 System.out.println("Test Passed");
 132         }
 133 }