1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
11 *******************************************************************************/
12 package org
.eclipse
.linuxtools
.lttng
.state
.model
;
14 import java
.util
.Stack
;
16 import org
.eclipse
.linuxtools
.lttng
.TraceDebug
;
17 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
;
18 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.ExecutionMode
;
19 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.ExecutionSubMode
;
20 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.ProcessStatus
;
21 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimestamp
;
24 * <b>LttngProcessState</b>
29 public class LttngProcessState
implements Cloneable
{
30 // ========================================================================
32 // =======================================================================
33 private Long cpu
= null;
34 private Long pid
= null;
35 private Long tgid
= null;
36 private String name
= null;
37 private TmfTimestamp creation_time
= null;
38 private String brand
= null;
39 private StateStrings
.ProcessType type
= null;
40 private Long current_function
= null;
41 private Long ppid
= null;
42 private TmfTimestamp insertion_time
= null;
43 private String pid_time
= null;
44 private Long free_events
= null;
45 private LttngExecutionState state
= null; // top of stack
46 private Stack
<LttngExecutionState
> execution_stack
= new Stack
<LttngExecutionState
>();
47 private Stack
<Long
> user_stack
= new Stack
<Long
>(); // user space
49 private String userTrace
= null; /* Associated file trace */
50 private Long target_pid
= null; /* target PID of the current event. */
52 // ========================================================================
54 // =======================================================================
55 public LttngProcessState(TmfTimestamp startTime
) {
59 this.name
= StateStrings
.ProcessStatus
.LTTV_STATE_UNNAMED
.getInName();
60 this.insertion_time
= startTime
;
64 public LttngProcessState(Long cpu
, Long pid
, Long tgid
,
65 String name
, TmfTimestamp startTime
) {
70 this.insertion_time
= startTime
;
74 // ========================================================================
76 // =======================================================================
78 this.brand
= StateStrings
.LTTV_STATE_UNBRANDED
;
79 this.type
= StateStrings
.ProcessType
.LTTV_STATE_USER_THREAD
;
80 this.current_function
= 0L;
82 // creation time defined when parent pid is known
83 // calling the setCreation_time method adjust the pid_time string
84 setCreation_time(new TmfTimestamp());
85 this.free_events
= 0L;
88 LttngExecutionState es
= new LttngExecutionState();
89 es
.setExec_mode(ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
);
90 es
.setExec_submode(ExecutionSubMode
.LTTV_STATE_SUBMODE_NONE
.getInName());
91 es
.setEntry_Time(this.insertion_time
);
92 es
.setChange_Time(this.insertion_time
);
93 es
.setCum_cpu_time(0L);
94 es
.setProc_status(ProcessStatus
.LTTV_STATE_RUN
);
95 this.execution_stack
.push(es
);
97 //TODO: This initialisation is present in C, however an entry in waiting fork may
98 //display incorrect states, there is a need for deeper compare of the initialisation phase
99 // es = new LttngExecutionState();
100 // es.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL);
101 // es.setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.getInName());
102 // es.setEntry_Time(this.insertion_time);
103 // es.setChange_Time(this.insertion_time);
104 // es.setCum_cpu_time(0L);
105 // es.setProc_status(ProcessStatus.LTTV_STATE_WAIT_FORK);
106 // this.execution_stack.push(es);
108 // point state to the top of the stack
113 @SuppressWarnings("unchecked")
114 public LttngProcessState
clone() {
115 LttngProcessState newState
= null;
118 newState
= (LttngProcessState
)super.clone();
121 // Basic type in java are immutable!
122 // Thus, using assignment ("=") on basic type is CORRECT,
123 // but we should ALWAYS use "new" or "clone()" on "non basic" type
124 newState
.cpu
= this.cpu
;
125 newState
.pid
= this.pid
;
126 newState
.tgid
= this.tgid
;
127 newState
.name
= this.name
;
128 newState
.brand
= this.brand
;
129 newState
.type
= this.type
;
130 newState
.current_function
= this.current_function
;
131 newState
.ppid
= this.ppid
;
132 newState
.pid_time
= this.pid_time
;
133 newState
.free_events
= this.free_events
;
134 newState
.userTrace
= this.userTrace
;
135 newState
.target_pid
= this.target_pid
;
137 // No clonable implemented in TMF, we will use copy constructor
138 // NOTE : we GOT to check for null to avoid crashing on null pointer here!
139 if ( this.creation_time
!= null ) {
140 newState
.creation_time
= new TmfTimestamp(this.creation_time
);
143 if ( this.creation_time
!= null ) {
144 newState
.insertion_time
= new TmfTimestamp(this.insertion_time
);
147 // Call clone on our own object is safe as Long it implements Clonable
148 newState
.state
= (LttngExecutionState
)this.state
.clone();
150 // Clone should work correctly for all stack object that contain basic java object (String, Long, etc...)
151 newState
.user_stack
= (Stack
<Long
>)this.user_stack
.clone();
154 // This is worst case : Stack that contain user defined object. We have to unstack it and clone every object in a new stack!
155 // Why does java does not call clone() for every object in the stack it clone? It would probably be too useful...
156 newState
.execution_stack
= new Stack
<LttngExecutionState
>();
158 // Work stack we will use to "pop" item
159 Stack
<LttngExecutionState
> tmpStack
= new Stack
<LttngExecutionState
>();
161 // First, we pop every ExecutionState, and insert a CLONED copy into our new cloned stack
162 while ( this.execution_stack
.empty() == false ) {
163 // Save a copy of the original reference
164 tmpStack
.push(this.execution_stack
.peek());
165 // Push a CLONED copy into the new stack while poping it from the original stack
166 newState
.execution_stack
.push( this.execution_stack
.pop().clone() );
169 // Second, we reinsert back our content into the original stack
170 while ( tmpStack
.empty() == false ) {
171 // Pop the cloned copy and push it back into the original stack
172 this.execution_stack
.push( tmpStack
.pop() );
175 catch ( CloneNotSupportedException e
) {
176 System
.out
.println("Cloning failed with : " + e
.getMessage() );
183 // ========================================================================
185 // =======================================================================
189 public Long
getPid() {
197 public void setPid(Long pid
) {
204 public Long
getTgid() {
212 public void setTgid(Long tgid
) {
219 public Long
getPpid() {
227 public void setPpid(Long ppid
) {
233 * When the parent pid is known, the creation time is also known and
240 public void setPpid(Long ppid
, TmfTimestamp creationTime
) {
245 if (creationTime
!= null) {
246 setCreation_time(creationTime
);
251 * @return the creation_time
253 public TmfTimestamp
getCreation_time() {
254 return creation_time
;
258 * @param creationTime
259 * the creation_time to set
261 public void setCreation_time(TmfTimestamp creationTime
) {
262 if ( (creationTime
!= null) && (pid
!= null) ) {
263 creation_time
= creationTime
;
264 StringBuilder sb
= new StringBuilder(this.pid
.toString() + "-"
265 + creationTime
.toString());
266 this.pid_time
= sb
.toString();
271 * @return the insertion_time
273 public TmfTimestamp
getInsertion_time() {
274 return insertion_time
;
278 * @param insertionTime
279 * the insertion_time to set
281 public void setInsertion_time(TmfTimestamp insertionTime
) {
282 insertion_time
= insertionTime
;
288 public String
getName() {
296 public void setName(String name
) {
303 public String
getBrand() {
311 public void setBrand(String brand
) {
316 * @return the prid_time
318 public String
getPid_time() {
325 public Long
getCpu() {
333 public void setCpu(Long cpu
) {
338 * @return the current_function
340 public Long
getCurrent_function() {
341 return current_function
;
345 * @param currentFunction
346 * the current_function to set
348 public void setCurrent_function(Long currentFunction
) {
349 current_function
= currentFunction
;
353 * @return the target_pid
355 public Long
getTarget_pid() {
361 * the target_pid to set
363 public void setTarget_pid(Long targetPid
) {
364 target_pid
= targetPid
;
368 * @return the free_events
370 public Long
getFree_events() {
376 * the free_events to set
378 public void setFree_events(Long freeEvents
) {
379 free_events
= freeEvents
;
383 * increment the nuber of free events
385 public void incrementFree_events() {
392 public LttngExecutionState
getState() {
400 public void setState(LttngExecutionState state
) {
407 public StateStrings
.ProcessType
getType() {
415 public void setType(StateStrings
.ProcessType type
) {
420 * @return the userTrace
422 public String
getUserTrace() {
428 * the userTrace to set
430 public void setUserTrace(String userTrace
) {
431 this.userTrace
= userTrace
;
435 public void clearUserStack() {
439 public void pushToUserStack(Long newState
) {
440 user_stack
.push(newState
);
443 public Long
popFromUserStack() {
444 if (user_stack
.size() <= 1) {
445 TraceDebug
.debug("Removing last item from user stack is not allowed! (popFromUserStack)");
449 return user_stack
.pop();
453 public Long
peekFromUserStack() {
454 return user_stack
.peek();
459 public void clearExecutionStack() {
460 execution_stack
.clear();
463 public void pushToExecutionStack(LttngExecutionState newState
) {
464 execution_stack
.push(newState
);
467 public LttngExecutionState
popFromExecutionStack() {
468 if (execution_stack
.size() <= 1) {
469 TraceDebug
.debug("Removing last item from execution stack is not allowed! (popFromExecutionStack)");
473 return execution_stack
.pop();
477 public LttngExecutionState
peekFromExecutionStack() {
478 return execution_stack
.peek();
481 public LttngExecutionState
getFirstElementFromExecutionStack() {
482 return execution_stack
.firstElement();
486 * MAIN : For testing only!
488 public static void main(String
[] args
) {
490 // !!! TESTING CLONE HERE !!!
492 // *** New object with some args set to "123"
493 LttngProcessState joie
= new LttngProcessState(new TmfTimestamp(123L, (byte) -9));
495 // Stack not empty by default??
496 System
.out
.println("Emptying stack... Trashing empty instance of : " + joie
.popFromExecutionStack() );
501 LttngExecutionState testEx1
= new LttngExecutionState();
502 testEx1
.setCum_cpu_time(123L);
503 testEx1
.setChange_Time(new TmfTimestamp(123L, (byte) -9));
504 testEx1
.setEntry_Time(new TmfTimestamp(123L, (byte) -9));
506 // Print testEx1 reference
507 System
.out
.println("testEx1 reference : " + testEx1
);
509 joie
.pushToExecutionStack(testEx1
);
510 joie
.pushToUserStack(123L);
514 // *** New object cloned from the first one
515 LttngProcessState joie2
= (LttngProcessState
)joie
.clone();
518 // *** Modification of the FIRST object : Everything to "456"
521 testEx1
.setCum_cpu_time(456L);
522 testEx1
.setChange_Time(new TmfTimestamp(456L, (byte) -9));
523 testEx1
.setEntry_Time(new TmfTimestamp(456L, (byte) -9));
525 // Push new object on stack of the FIRST object
526 LttngExecutionState testEx2
= new LttngExecutionState();
527 testEx2
.setCum_cpu_time(456L);
528 joie
.pushToExecutionStack(testEx2
);
529 joie
.pushToUserStack(456L);
532 // *** TEST : Everything should be "123L" stil
533 System
.out
.println("123 == " + joie2
.getCpu() );
534 System
.out
.println("123 == " + joie2
.getName() );
536 LttngExecutionState newtestEx1
= joie2
.popFromExecutionStack();
537 // Print newtestEx1 reference
538 System
.out
.println("testEx1 reference : " + newtestEx1
);
540 System
.out
.println("123 == " + newtestEx1
.getCum_cpu_time() );
541 System
.out
.println("123 == " + joie2
.popFromUserStack() );
543 // *** LAST TEST : The joie2 stack should be empty, only joie1 stack contains more than 1 object
545 System
.out
.println("123 == " + joie2
.popFromExecutionStack().getCum_cpu_time() );
547 catch ( Exception e
) {
548 System
.out
.println("All fine");