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_USER_MODE
);
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 //This second entry is needed when processes are created via a Fork event.
98 es
= new LttngExecutionState();
99 es
.setExec_mode(ExecutionMode
.LTTV_STATE_SYSCALL
);
101 .setExec_submode(ExecutionSubMode
.LTTV_STATE_SUBMODE_NONE
103 es
.setEntry_Time(this.insertion_time
);
104 es
.setChange_Time(this.insertion_time
);
105 es
.setCum_cpu_time(0L);
106 es
.setProc_status(ProcessStatus
.LTTV_STATE_WAIT_FORK
);
107 this.execution_stack
.push(es
);
109 // point state to the top of the stack
114 @SuppressWarnings("unchecked")
115 public LttngProcessState
clone() {
116 LttngProcessState newState
= null;
119 newState
= (LttngProcessState
)super.clone();
122 // Basic type in java are immutable!
123 // Thus, using assignment ("=") on basic type is CORRECT,
124 // but we should ALWAYS use "new" or "clone()" on "non basic" type
125 newState
.cpu
= this.cpu
;
126 newState
.pid
= this.pid
;
127 newState
.tgid
= this.tgid
;
128 newState
.name
= this.name
;
129 newState
.brand
= this.brand
;
130 newState
.type
= this.type
;
131 newState
.current_function
= this.current_function
;
132 newState
.ppid
= this.ppid
;
133 newState
.pid_time
= this.pid_time
;
134 newState
.free_events
= this.free_events
;
135 newState
.userTrace
= this.userTrace
;
136 newState
.target_pid
= this.target_pid
;
138 // No clonable implemented in TMF, we will use copy constructor
139 // NOTE : we GOT to check for null to avoid crashing on null pointer here!
140 if ( this.creation_time
!= null ) {
141 newState
.creation_time
= new TmfTimestamp(this.creation_time
);
144 if ( this.creation_time
!= null ) {
145 newState
.insertion_time
= new TmfTimestamp(this.insertion_time
);
148 // Call clone on our own object is safe as Long it implements Clonable
149 newState
.state
= (LttngExecutionState
)this.state
.clone();
151 // Clone should work correctly for all stack object that contain basic java object (String, Long, etc...)
152 newState
.user_stack
= (Stack
<Long
>)this.user_stack
.clone();
155 // This is worst case : Stack that contain user defined object. We have to unstack it and clone every object in a new stack!
156 // Why does java does not call clone() for every object in the stack it clone? It would probably be too useful...
157 newState
.execution_stack
= new Stack
<LttngExecutionState
>();
159 // Work stack we will use to "pop" item
160 Stack
<LttngExecutionState
> tmpStack
= new Stack
<LttngExecutionState
>();
162 // First, we pop every ExecutionState, and insert a CLONED copy into our new cloned stack
163 while ( this.execution_stack
.empty() == false ) {
164 // Save a copy of the original reference
165 tmpStack
.push(this.execution_stack
.peek());
166 // Push a CLONED copy into the new stack while poping it from the original stack
167 newState
.execution_stack
.push( this.execution_stack
.pop().clone() );
170 // Second, we reinsert back our content into the original stack
171 while ( tmpStack
.empty() == false ) {
172 // Pop the cloned copy and push it back into the original stack
173 this.execution_stack
.push( tmpStack
.pop() );
176 catch ( CloneNotSupportedException e
) {
177 System
.out
.println("Cloning failed with : " + e
.getMessage() );
184 // ========================================================================
186 // =======================================================================
190 public Long
getPid() {
198 public void setPid(Long pid
) {
205 public Long
getTgid() {
213 public void setTgid(Long tgid
) {
220 public Long
getPpid() {
228 public void setPpid(Long ppid
) {
234 * When the parent pid is known, the creation time is also known and
241 public void setPpid(Long ppid
, TmfTimestamp creationTime
) {
246 if (creationTime
!= null) {
247 setCreation_time(creationTime
);
252 * @return the creation_time
254 public TmfTimestamp
getCreation_time() {
255 return creation_time
;
259 * @param creationTime
260 * the creation_time to set
262 public void setCreation_time(TmfTimestamp creationTime
) {
263 if ( (creationTime
!= null) && (pid
!= null) ) {
264 creation_time
= creationTime
;
265 StringBuilder sb
= new StringBuilder(this.pid
.toString() + "-"
266 + creationTime
.toString());
267 this.pid_time
= sb
.toString();
272 * @return the insertion_time
274 public TmfTimestamp
getInsertion_time() {
275 return insertion_time
;
279 * @param insertionTime
280 * the insertion_time to set
282 public void setInsertion_time(TmfTimestamp insertionTime
) {
283 insertion_time
= insertionTime
;
289 public String
getName() {
297 public void setName(String name
) {
304 public String
getBrand() {
312 public void setBrand(String brand
) {
317 * @return the prid_time
319 public String
getPid_time() {
326 public Long
getCpu() {
334 public void setCpu(Long cpu
) {
339 * @return the current_function
341 public Long
getCurrent_function() {
342 return current_function
;
346 * @param currentFunction
347 * the current_function to set
349 public void setCurrent_function(Long currentFunction
) {
350 current_function
= currentFunction
;
354 * @return the target_pid
356 public Long
getTarget_pid() {
362 * the target_pid to set
364 public void setTarget_pid(Long targetPid
) {
365 target_pid
= targetPid
;
369 * @return the free_events
371 public Long
getFree_events() {
377 * the free_events to set
379 public void setFree_events(Long freeEvents
) {
380 free_events
= freeEvents
;
384 * increment the nuber of free events
386 public void incrementFree_events() {
393 public LttngExecutionState
getState() {
401 public void setState(LttngExecutionState state
) {
408 public StateStrings
.ProcessType
getType() {
416 public void setType(StateStrings
.ProcessType type
) {
421 * @return the userTrace
423 public String
getUserTrace() {
429 * the userTrace to set
431 public void setUserTrace(String userTrace
) {
432 this.userTrace
= userTrace
;
436 public void clearUserStack() {
440 public void pushToUserStack(Long newState
) {
441 user_stack
.push(newState
);
444 public Long
popFromUserStack() {
445 if (user_stack
.size() <= 1) {
446 TraceDebug
.debug("Removing last item from user stack is not allowed! (popFromUserStack)");
450 return user_stack
.pop();
454 public Long
peekFromUserStack() {
455 return user_stack
.peek();
460 public void clearExecutionStack() {
461 execution_stack
.clear();
464 public void pushToExecutionStack(LttngExecutionState newState
) {
465 execution_stack
.push(newState
);
469 public LttngExecutionState
popFromExecutionStack() {
470 if (execution_stack
.size() <= 1) {
471 TraceDebug
.debug("Removing last item from execution stack is not allowed! (popFromExecutionStack)");
475 LttngExecutionState popedState
= execution_stack
.pop();
476 // adjust current state to the new top
477 setState(peekFromExecutionStack());
482 public LttngExecutionState
peekFromExecutionStack() {
483 return execution_stack
.peek();
486 public LttngExecutionState
getFirstElementFromExecutionStack() {
487 return execution_stack
.firstElement();
491 * MAIN : For testing only!
493 public static void main(String
[] args
) {
495 // !!! TESTING CLONE HERE !!!
497 // *** New object with some args set to "123"
498 LttngProcessState joie
= new LttngProcessState(new TmfTimestamp(123L, (byte) -9));
500 // Stack not empty by default??
501 System
.out
.println("Emptying stack... Trashing empty instance of : " + joie
.popFromExecutionStack() );
506 LttngExecutionState testEx1
= new LttngExecutionState();
507 testEx1
.setCum_cpu_time(123L);
508 testEx1
.setChange_Time(new TmfTimestamp(123L, (byte) -9));
509 testEx1
.setEntry_Time(new TmfTimestamp(123L, (byte) -9));
511 // Print testEx1 reference
512 System
.out
.println("testEx1 reference : " + testEx1
);
514 joie
.pushToExecutionStack(testEx1
);
515 joie
.pushToUserStack(123L);
519 // *** New object cloned from the first one
520 LttngProcessState joie2
= (LttngProcessState
)joie
.clone();
523 // *** Modification of the FIRST object : Everything to "456"
526 testEx1
.setCum_cpu_time(456L);
527 testEx1
.setChange_Time(new TmfTimestamp(456L, (byte) -9));
528 testEx1
.setEntry_Time(new TmfTimestamp(456L, (byte) -9));
530 // Push new object on stack of the FIRST object
531 LttngExecutionState testEx2
= new LttngExecutionState();
532 testEx2
.setCum_cpu_time(456L);
533 joie
.pushToExecutionStack(testEx2
);
534 joie
.pushToUserStack(456L);
537 // *** TEST : Everything should be "123L" stil
538 System
.out
.println("123 == " + joie2
.getCpu() );
539 System
.out
.println("123 == " + joie2
.getName() );
541 LttngExecutionState newtestEx1
= joie2
.popFromExecutionStack();
542 // Print newtestEx1 reference
543 System
.out
.println("testEx1 reference : " + newtestEx1
);
545 System
.out
.println("123 == " + newtestEx1
.getCum_cpu_time() );
546 System
.out
.println("123 == " + joie2
.popFromUserStack() );
548 // *** LAST TEST : The joie2 stack should be empty, only joie1 stack contains more than 1 object
550 System
.out
.println("123 == " + joie2
.popFromExecutionStack().getCum_cpu_time() );
552 catch ( Exception e
) {
553 System
.out
.println("All fine");