KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > clif > scenario > util > isac > engine > behavior > BehaviorsPool


1 /*
2  * CLIF is a Load Injection Framework
3  * Copyright (C) 2004 France Telecom R&D
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * CLIF
20  *
21  * Contact: clif@objectweb.org
22  */

23 package org.objectweb.clif.scenario.util.isac.engine.behavior;
24
25 import java.util.Vector JavaDoc;
26
27 import org.objectweb.clif.datacollector.api.DataCollectorWrite;
28 import org.objectweb.clif.scenario.util.isac.engine.IsacScenarioEngine;
29 import org.objectweb.clif.scenario.util.isac.engine.behavior.node.ExecutableNode;
30 import org.objectweb.clif.scenario.util.isac.engine.loadprofile.GroupDescriptionManager;
31 import org.objectweb.clif.scenario.util.isac.engine.sessionobject.SessionObjectManager;
32 import org.objectweb.clif.scenario.util.isac.exception.IsacRuntimeException;
33 import org.objectweb.clif.scenario.util.isac.loadprofile.GroupDescription;
34 import org.objectweb.clif.scenario.util.isac.util.BooleanHolder;
35 import org.objectweb.clif.scenario.util.isac.util.SessionObjectHashtable;
36 import org.objectweb.clif.scenario.util.isac.util.IntHolder;
37 import org.objectweb.util.monolog.api.BasicLevel;
38 import org.objectweb.util.monolog.api.Logger;
39
40 /**
41  * This class implements a bool of behaviors, each group will have a
42  * beaviorsPool to manage all it behaviors (add, remove...)
43  *
44  * @author JC Meillaud
45  * @author A Peyrard
46  */

47 public class BehaviorsPool {
48     // logger
49
static Logger log = IsacScenarioEngine.logger.getLogger(BehaviorsPool.class
50             .getName());
51
52     /////////////////////
53
// attributes
54
/////////////////////
55

56     // ATTRIBUTES STORING DATA TO CREATE ALL BEHAVIORS THREADS
57

58     // the id of the current group which will be manage by this pool
59
private Integer JavaDoc groupId;
60
61     // the manageers
62
private GroupDescriptionManager groupDescriptionManager;
63
64     private BehaviorManager behaviorManager;
65
66     private SessionObjectManager sessionObjectManager;
67
68     private boolean forceStopThread;
69
70     // ATTRIBUTES INITIALIZED WITH THE DATAS INFORMATIONS
71
// size of the pool
72
private int size;
73
74     // table storing each thread of the pool
75
private Thread JavaDoc[] poolThread;
76
77     // ATTRIBUTES FOR ALL BEHAVIORS THREADS
78

79     // some boolean references to switch between state
80
private volatile BooleanHolder stopped;
81
82     private volatile BooleanHolder suspended;
83
84     // suspend lock shared between all threads, to switch to suspend mode
85
private Object JavaDoc suspendLock;
86
87     // lock used by the threads to notify the group execution thread
88
private Object JavaDoc groupExecutionLock;
89
90     // client interface to send report of actions
91
private DataCollectorWrite dataCollectorWrite;
92
93     // lock for this interface
94
private Object JavaDoc dataCollectorWrite_lock;
95
96     // ATTRIBUTES FOR BEHAVIORS WHICH BELONG TO THIS POOL
97

98     // lock used to lock behaviors thread activity, or to notify some threads
99
private Object JavaDoc activitiesLock;
100
101     // int shared between behaviors to store the number of
102
// behaviors which are suspended
103
private IntHolder totalSuspendedBehaviors;
104
105     // int shared between behaviors to store the number of thread required
106
// in order to wait the last thread
107
private IntHolder behaviorsRequiredNumber;
108
109     // vector storing all running behaviors ;
110
private Vector JavaDoc behaviorsRunning;
111
112     // lock to wait the reaction of all thread when whe awake it or put in sleep
113
// some of them
114
// use to synchronize references access too
115
private Object JavaDoc poolLock;
116
117     // lock used by hte threads to execute some timers
118
private Object JavaDoc timerLock;
119
120     // an int storing the number of behaviors threads alive
121
private IntHolder behaviorsThreadsAlive;
122
123     private String JavaDoc bladeId;
124
125     /**
126      * Constructor, create a new bahaviorspool
127      *
128      * @param groupId
129      * The current group id
130      * @param groupDescriptionManager
131      * The group description manager
132      * @param behaviorManager
133      * The behavior manager
134      * @param sessionObjectManager
135      * The session manager
136      * @param stopped
137      * The stopped boolean state
138      * @param suspended
139      * The suspended boolena state
140      * @param suspendLock
141      * The lock to execute suspend on behaviors
142      * @param groupExecutionLock
143      * The lock to notify the group execution
144      * @param dcw
145      * The data collector write interface
146      * @param dcwl
147      * The lock for this interface
148      * @param tl
149      * The lock to wait during timers
150      */

151     public BehaviorsPool(String JavaDoc bladeId, Integer JavaDoc groupId,
152             GroupDescriptionManager groupDescriptionManager,
153             BehaviorManager behaviorManager,
154             SessionObjectManager sessionObjectManager, BooleanHolder stopped,
155             BooleanHolder suspended, Object JavaDoc suspendLock,
156             Object JavaDoc groupExecutionLock, DataCollectorWrite dcw, Object JavaDoc dcwl,
157             Object JavaDoc tl)
158     {
159         this.bladeId = bladeId;
160         this.groupId = groupId;
161         this.groupDescriptionManager = groupDescriptionManager;
162         this.behaviorManager = behaviorManager;
163         this.sessionObjectManager = sessionObjectManager;
164         this.stopped = stopped;
165         this.suspended = suspended;
166         this.suspendLock = suspendLock;
167         this.groupExecutionLock = groupExecutionLock;
168         this.dataCollectorWrite = dcw;
169         this.dataCollectorWrite_lock = dcwl;
170         this.timerLock = tl;
171     }
172
173     /**
174      * This methods initialize all behaviors threads, whith all the datas stored
175      * in the managers
176      */

177     public void initializeBehaviorsThreads() {
178         // init the lock of the pool
179
this.poolLock = new Object JavaDoc();
180         // init the lock for behaviors activities
181
this.activitiesLock = new Object JavaDoc();
182         // init number of threads suspended, and threads running vector
183
this.totalSuspendedBehaviors = this.groupDescriptionManager
184                 .getNumberThreadWaitingForAGroup(groupId);
185         this.behaviorsRunning = this.groupDescriptionManager
186                 .getGroupRunningBehaviors(groupId);
187         this.behaviorsRequiredNumber = this.groupDescriptionManager
188                 .getNumberThreadRunningRequiredForAGroup(groupId);
189         // get the number max of behaviors
190
this.size = this.groupDescriptionManager
191                 .getMaximumBehaviorsForAGroup(this.groupId);
192         // init the behaviors threads table
193
this.poolThread = new Thread JavaDoc[this.size];
194         // prepare the initialization of the behaviors
195
// get the behaviorId for this group
196
String JavaDoc behaviorId = this.groupDescriptionManager.getGroupDescription(
197                 this.groupId).getBehaviorId();
198         // get the stopping mode
199
this.forceStopThread = this.groupDescriptionManager
200                 .getGroupDescription(this.groupId).isForceStop();
201         // get the executable node representing the behavior
202
ExecutableNode executableNode = this.behaviorManager
203                 .getBehavior(behaviorId);
204         this.behaviorsThreadsAlive = new IntHolder(0);
205         // create all the behaviors threads
206
for (int i = 0; i < this.size; i++) {
207             // get a newly created table containing the sessions
208
SessionObjectHashtable clonedSessionsObjects = (SessionObjectHashtable) (this.sessionObjectManager
209                     .getSessionObjectsForABehavior(behaviorId)).clone();
210             // init a new thread
211
poolThread[i] = new BehaviorExecutionPooledThread(bladeId, i,
212                     executableNode, clonedSessionsObjects, this.suspendLock,
213                     this.poolLock, this.timerLock, this.activitiesLock,
214                     this.groupExecutionLock, this.dataCollectorWrite,
215                     this.dataCollectorWrite_lock, this.stopped, this.suspended,
216                     this.behaviorsRunning, this.totalSuspendedBehaviors,
217                     this.behaviorsRequiredNumber, this.behaviorsThreadsAlive);
218             poolThread[i].setDaemon(true);
219             poolThread[i].start();
220         }
221     }
222
223     /**
224      * This method will be used to set the number of behaviors running
225      *
226      * @param number
227      * The number of thread runing expected
228      * @return true if the number of threads asked was already right
229      */

230     public boolean setNumberOfThreadsRunning(int number) {
231         // synchronize access with the pool lock
232
int behaviorsRunningSize = 0;
233         // init a boolean which store if this group is finish
234
boolean haveFinished = false;
235         synchronized (this.poolLock) {
236             // get the current number of behaviors running
237
behaviorsRunningSize = this.behaviorsRunning.size();
238             log.log(BasicLevel.INFO,"nb-THREADS="+behaviorsRunningSize) ;
239             // test if we have finished this group
240
if (number == GroupDescription.END) {
241                 // set number asked to 0
242
number = 0 ;
243                 // maybe we have finished the execution of this pool
244
haveFinished = true;
245             }
246             // do things we have to do in the lock for the three case
247
if (behaviorsRunningSize < number) {
248                 // set the number of threads required
249
this.behaviorsRequiredNumber.setIntValue(number
250                         - behaviorsRunningSize);
251                 if (IsacScenarioEngine.DEBUG_ON) {
252                     log.log(BasicLevel.DEBUG, " *POOL* Add="
253                             + (number - behaviorsRunningSize));
254                 }
255             } else if (behaviorsRunningSize > number) {
256                 if (this.forceStopThread) {
257                     // get the difference between the thread required and the
258
// running
259
// one
260
int numberOfThreadToStop = behaviorsRunningSize - number;
261                     // set the number of threads required
262
this.behaviorsRequiredNumber
263                             .setIntValue(numberOfThreadToStop);
264                     if (IsacScenarioEngine.DEBUG_ON) {
265                         log.log(BasicLevel.DEBUG, " *POOL* Stop="
266                                 + numberOfThreadToStop);
267                     }
268                     // stop some threads
269
for (int i = 0; i < numberOfThreadToStop; i++) {
270                         ((BehaviorExecutionPooledThread) this.behaviorsRunning
271                                 .elementAt(i)).setLocalStopped(true);
272                     }
273                     // awake threads which are in timer, like this they will
274
// reanalyse
275
// their state
276
synchronized (timerLock) {
277                         this.timerLock.notifyAll();
278                     }
279                     log.log(BasicLevel.DEBUG,
280                             " *POOL* Wait for stopped thread");
281                     // wait the last stopping thread
282
if (this.behaviorsRequiredNumber.getIntValue() != 0) {
283                         try {
284                             this.poolLock.wait();
285                         } catch (InterruptedException JavaDoc ex) {
286                             throw new IsacRuntimeException(
287                                     "Unable to wait the stop of surplus threads",ex);
288                         }
289                     }
290                     log.log(BasicLevel.DEBUG,
291                             " *POOL* All thread have been stopped !!!!");
292                 } else {
293                     log
294                             .log(BasicLevel.WARN, " * POOL * Still "
295                                     + this.behaviorsRunning.size()
296                                     + " threads running");
297                     // there is still some runnings threads
298
haveFinished = false ;
299                 }
300             }
301         }
302
303         // we could have three case
304
// first one, we have the right number of running threads
305
if (behaviorsRunningSize == number) {
306             // do nothing
307
log.log(BasicLevel.DEBUG,
308                     " *POOL* We have the right number of thread");
309         } else
310         // second case, we need to add some behaviors
311
if (behaviorsRunningSize < number) {
312             // awake the threads needed
313
for (int i = behaviorsRunningSize; i < number; i++) {
314                 synchronized (this.activitiesLock) {
315                     this.activitiesLock.notify();
316                 }
317             }
318             synchronized (this.poolLock) {
319                 if (this.behaviorsRequiredNumber.getIntValue() != 0) {
320                     // wait the right number of running thread
321
log.log(BasicLevel.DEBUG, " *POOL* Wait thread added");
322                     try {
323                         this.poolLock.wait();
324                     } catch (InterruptedException JavaDoc ex) {
325                         throw new IsacRuntimeException(
326                                 "Unable to wait the launch of requied threads");
327                     }
328                 }
329             }
330             log.log(BasicLevel.DEBUG,
331                     " *POOL* All thread have been added !!!!");
332         }
333         // the last one is managed in the synchronized part
334

335         // return the finished state
336
return haveFinished ;
337     }
338
339     /**
340      * This method wait the suspend state of all threads
341      */

342     public void waitForSuspendState() {
343         synchronized (this.poolLock) {
344             if (this.behaviorsRunning.size() != this.totalSuspendedBehaviors
345                     .getIntValue()) {
346                 try {
347                     this.poolLock.wait();
348                 } catch (InterruptedException JavaDoc iex) {
349                     throw new IsacRuntimeException(
350                             "Unable to wait the suspend state",iex);
351                 }
352             }
353         }
354     }
355
356     /**
357      * This method wait the resume state of all threads
358      */

359     public void waitForResumeState() {
360         synchronized (this.poolLock) {
361             if (this.totalSuspendedBehaviors.getIntValue() != 0) {
362                 try {
363                     this.poolLock.wait();
364                 } catch (InterruptedException JavaDoc iex) {
365                     throw new IsacRuntimeException(
366                             "Unable to wait the resume state",iex);
367                 }
368             }
369         }
370     }
371
372     /**
373      * Method returns the number of thread which are still alive
374      *
375      * @return The number of threads alive
376      */

377     public int getNumberOfThreadAlive() {
378         return this.behaviorsThreadsAlive.getIntValue();
379     }
380
381     /**
382      * Method which awake all threads of the pool
383      */

384     public void awakeAllThreads() {
385         synchronized (this.activitiesLock) {
386             this.activitiesLock.notifyAll();
387         }
388     }
389 }
Popular Tags