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 package gc.gctests.gctest04;
25 
26 import nsk.share.test.*;
27 import nsk.share.gc.*;
28 
29 //reqgen.java
30 
31 /*    stress testing
32  reqgen is a subtype of Thread which generates
33  request to allocate small objects ( 8 ~ 32k), short live time ( 5 ~ 10 ms)
34  reqdisp is a subtype of Thread which dispatches request
35  and create a livethread object to allocate the requested memory
36  and simulate its life time.
37  */
38 
39 class bufreq
40 {
41   int bufsz;       // memory size
42   int life;        // live time of the object
43   bufreq next;
44 
bufreq(int bufsz, int t)45   bufreq(int bufsz, int t)
46   {
47     this.bufsz = bufsz;
48         this.life = t;
49         this.next = null;
50   }
51 
setnext(bufreq b)52   public void setnext(bufreq b)
53   {
54     next = b;
55   }
56 
getnext()57   public bufreq getnext()
58   {
59     return next;
60   }
61 
getsize()62   public int getsize()
63   {
64     return bufsz;
65   }
66 
livetime()67   public int livetime()
68   {
69     return life;
70   }
71 }
72 
73 class queue
74 {
75     bufreq head;
76     bufreq tail;
77     int limit;
78     int count;
79 
queue(int newLimit)80     queue(int newLimit)
81     {
82         head = null;
83         tail = null;
84         limit = newLimit;
85         count = 0;
86     }
87 
okToContinue()88   public boolean okToContinue()
89   {
90         return (count < limit);
91   }
92 
append(bufreq b)93   public synchronized void append(bufreq b)
94   {
95     count++;
96     if ( tail == null ) // head must be null too
97     {
98             head = tail = b;
99         return;
100     }
101     tail.setnext(b);
102     tail = b;
103   }
104 
remove()105   public synchronized bufreq remove()
106   {
107     if ( head == null ) return null;
108     bufreq  buf = head;
109     head = head.getnext();
110     if ( head == null )  // only one element in the queue
111     {
112             tail = head = null;
113     }
114     return buf;
115   }
116 }
117 
118 class  reqgen extends Thread {
119   queue    req;
120   int      maxsz;
121   int      minsz;
122   int      maxlive;
123   int      minlive;
124   int     amda;
125 
reqgen(queue req, int t)126   reqgen(queue req, int t)
127   {
128     this.req = req;
129     amda = t;
130   }
131 
setsize(int s1, int s2)132   public void setsize(int s1, int s2)
133   {
134        maxsz = s2;
135        minsz = s1;
136   }
137 
setlive(int t1, int t2)138   public void setlive(int t1, int t2)
139   {
140     maxlive = t2;
141     minlive = t1;
142   }
143 
run()144   public void run()
145   {
146     bufreq  buf;
147     int sz;
148     int t;
149 
150     sz = minsz;
151     t =  minlive;
152     while ( req.okToContinue() )
153     {
154         buf = new bufreq(sz, t);
155 
156         sz = ( 2*sz);
157 
158             if ( sz > maxsz)
159             {
160                 sz = minsz;
161         }
162 
163         t = ( 2 * t );
164             if ( t >  maxlive)
165             {
166             t = minlive;
167         }
168 
169             req.append(buf);
170 
171         try
172         {
173                 sleep(amda);
174         }
175         catch(InterruptedException e) {}
176       }
177   }
178 
nextreq()179   public bufreq nextreq()
180   {
181     return req.remove();
182   }
183 
184 }
185 
186 // buffer request dispatcher and allocator
187 class  reqdisp extends Thread {
188   queue req;
189 
reqdisp(queue q )190   reqdisp(queue q )
191   {
192     req = q;
193   }
194 
run()195   public void run()
196   {
197     bufreq r;
198     livethread lt;
199 
200     while ( req.okToContinue() )
201     {
202             r = req.remove();
203         if ( r != null )
204             {
205                 lt = new livethread(r);
206             lt.start();
207         }
208       // simulate the interarrival time
209         try
210         {
211             sleep((int)(LocalRandom.random() * 20));
212         }
213         catch (InterruptedException e) {}
214     }
215   }
216 
217 
218 }
219 
220 class livethread extends Thread {
221   bufreq req;
222 
livethread(bufreq r)223   livethread(bufreq r)
224   {
225     req = r;
226   }
227 
run()228   public void run()
229   {
230     int buf[];
231 
232     buf =  new int[req.getsize()];
233 
234     // simulate the life time of the created object
235     // if live time is 0, that means forever
236     if ( req.livetime() == 0 )
237     {
238        while ( true )
239        {
240           try
241           {
242              sleep(10000);
243           }
244           catch (InterruptedException e) {}
245        }
246     }
247     else
248     {
249        try
250        {
251           sleep(req.livetime());
252        }
253        catch (InterruptedException e) {}
254 
255     }
256     // live object is outdated, should be GC'ed
257   }
258 }
259