Commit | Line | Data |
---|---|---|
5d10d135 ASL |
1 | /******************************************************************************* |
2 | * Copyright (c) 2009 Ericsson | |
3 | * | |
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 | |
8 | * | |
9 | * Contributors: | |
10 | * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | package org.eclipse.linuxtools.lttng.state.model; | |
13 | ||
14 | import java.util.Stack; | |
15 | ||
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; | |
58c60db3 | 21 | import org.eclipse.linuxtools.tmf.event.TmfTimestamp; |
5d10d135 ASL |
22 | |
23 | /** | |
24 | * <b>LttngProcessState</b> | |
25 | * | |
26 | * @author alvaro | |
27 | * | |
28 | */ | |
29 | public class LttngProcessState implements Cloneable { | |
30 | // ======================================================================== | |
31 | // Data | |
32 | // ======================================================================= | |
33 | private Long cpu = null; | |
34 | private Long pid = null; | |
35 | private Long tgid = null; | |
36 | private String name = null; | |
58c60db3 | 37 | private TmfTimestamp creation_time = null; |
5d10d135 ASL |
38 | private String brand = null; |
39 | private StateStrings.ProcessType type = null; | |
40 | private Long current_function = null; | |
41 | private Long ppid = null; | |
58c60db3 | 42 | private TmfTimestamp insertion_time = null; |
5d10d135 ASL |
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 | |
48 | ||
49 | private String userTrace = null; /* Associated file trace */ | |
50 | private Long target_pid = null; /* target PID of the current event. */ | |
58c60db3 | 51 | |
5d10d135 ASL |
52 | // ======================================================================== |
53 | // Constructor | |
54 | // ======================================================================= | |
58c60db3 | 55 | public LttngProcessState(TmfTimestamp startTime) { |
5d10d135 ASL |
56 | this.cpu = 0L; |
57 | this.pid = 0L; | |
58 | this.tgid = 0L; | |
59 | this.name = StateStrings.ProcessStatus.LTTV_STATE_UNNAMED.getInName(); | |
60 | this.insertion_time = startTime; | |
5d10d135 ASL |
61 | init(); |
62 | } | |
63 | ||
64 | public LttngProcessState(Long cpu, Long pid, Long tgid, | |
58c60db3 | 65 | String name, TmfTimestamp startTime) { |
5d10d135 ASL |
66 | this.cpu = cpu; |
67 | this.pid = pid; | |
68 | this.tgid = tgid; | |
69 | this.name = name; | |
70 | this.insertion_time = startTime; | |
5d10d135 ASL |
71 | init(); |
72 | } | |
73 | ||
74 | // ======================================================================== | |
75 | // Methods | |
76 | // ======================================================================= | |
77 | private void init() { | |
78 | this.brand = StateStrings.LTTV_STATE_UNBRANDED; | |
79 | this.type = StateStrings.ProcessType.LTTV_STATE_USER_THREAD; | |
80 | this.current_function = 0L; | |
81 | this.ppid = 0L; | |
58c60db3 FC |
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()); | |
5d10d135 ASL |
85 | this.free_events = 0L; |
86 | ||
58c60db3 | 87 | // Initialize stack |
5d10d135 | 88 | LttngExecutionState es = new LttngExecutionState(); |
41dc35d0 | 89 | es.setExec_mode(ExecutionMode.LTTV_STATE_MODE_UNKNOWN); |
5d10d135 ASL |
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); | |
41dc35d0 FC |
96 | |
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); | |
5d10d135 ASL |
107 | |
108 | // point state to the top of the stack | |
109 | this.state = es; | |
110 | } | |
111 | ||
cc6eec3e | 112 | @Override |
5d10d135 ASL |
113 | @SuppressWarnings("unchecked") |
114 | public LttngProcessState clone() { | |
115 | LttngProcessState newState = null; | |
116 | ||
117 | try { | |
118 | newState = (LttngProcessState)super.clone(); | |
119 | ||
120 | // *** IMPORTANT *** | |
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; | |
58c60db3 FC |
136 | |
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); | |
141 | } | |
142 | ||
143 | if ( this.creation_time != null ) { | |
144 | newState.insertion_time = new TmfTimestamp(this.insertion_time); | |
145 | } | |
5d10d135 ASL |
146 | |
147 | // Call clone on our own object is safe as Long it implements Clonable | |
148 | newState.state = (LttngExecutionState)this.state.clone(); | |
149 | ||
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(); | |
152 | ||
153 | ||
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>(); | |
157 | ||
158 | // Work stack we will use to "pop" item | |
159 | Stack<LttngExecutionState> tmpStack = new Stack<LttngExecutionState>(); | |
160 | ||
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() ); | |
167 | } | |
168 | ||
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() ); | |
173 | } | |
174 | } | |
175 | catch ( CloneNotSupportedException e ) { | |
176 | System.out.println("Cloning failed with : " + e.getMessage() ); | |
177 | } | |
178 | ||
179 | return newState; | |
180 | } | |
181 | ||
182 | ||
183 | // ======================================================================== | |
184 | // Methods | |
185 | // ======================================================================= | |
186 | /** | |
187 | * @return the pid | |
188 | */ | |
189 | public Long getPid() { | |
190 | return pid; | |
191 | } | |
192 | ||
193 | /** | |
194 | * @param pid | |
195 | * the pid to set | |
196 | */ | |
197 | public void setPid(Long pid) { | |
198 | this.pid = pid; | |
199 | } | |
200 | ||
201 | /** | |
202 | * @return the tgid | |
203 | */ | |
204 | public Long getTgid() { | |
205 | return tgid; | |
206 | } | |
207 | ||
208 | /** | |
209 | * @param tgid | |
210 | * the tgid to set | |
211 | */ | |
212 | public void setTgid(Long tgid) { | |
213 | this.tgid = tgid; | |
214 | } | |
215 | ||
216 | /** | |
217 | * @return the ppid | |
218 | */ | |
219 | public Long getPpid() { | |
220 | return ppid; | |
221 | } | |
222 | ||
223 | /** | |
224 | * @param ppid | |
225 | * the ppid to set | |
226 | */ | |
227 | public void setPpid(Long ppid) { | |
228 | this.ppid = ppid; | |
229 | } | |
230 | ||
231 | /** | |
232 | * <p> | |
233 | * When the parent pid is known, the creation time is also known and | |
234 | * requires update | |
235 | * </p> | |
236 | * | |
237 | * @param ppid | |
238 | * the ppid to set | |
239 | */ | |
58c60db3 | 240 | public void setPpid(Long ppid, TmfTimestamp creationTime) { |
5d10d135 ASL |
241 | if (ppid != null) { |
242 | this.ppid = ppid; | |
243 | } | |
244 | ||
245 | if (creationTime != null) { | |
246 | setCreation_time(creationTime); | |
247 | } | |
248 | } | |
249 | ||
250 | /** | |
251 | * @return the creation_time | |
252 | */ | |
58c60db3 | 253 | public TmfTimestamp getCreation_time() { |
5d10d135 ASL |
254 | return creation_time; |
255 | } | |
256 | ||
257 | /** | |
258 | * @param creationTime | |
259 | * the creation_time to set | |
260 | */ | |
58c60db3 | 261 | public void setCreation_time(TmfTimestamp creationTime) { |
5d10d135 ASL |
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(); | |
267 | } | |
268 | } | |
269 | ||
270 | /** | |
271 | * @return the insertion_time | |
272 | */ | |
58c60db3 | 273 | public TmfTimestamp getInsertion_time() { |
5d10d135 ASL |
274 | return insertion_time; |
275 | } | |
276 | ||
277 | /** | |
278 | * @param insertionTime | |
279 | * the insertion_time to set | |
280 | */ | |
58c60db3 | 281 | public void setInsertion_time(TmfTimestamp insertionTime) { |
5d10d135 ASL |
282 | insertion_time = insertionTime; |
283 | } | |
284 | ||
285 | /** | |
286 | * @return the name | |
287 | */ | |
288 | public String getName() { | |
289 | return name; | |
290 | } | |
291 | ||
292 | /** | |
293 | * @param name | |
294 | * the name to set | |
295 | */ | |
296 | public void setName(String name) { | |
297 | this.name = name; | |
298 | } | |
299 | ||
300 | /** | |
301 | * @return the brand | |
302 | */ | |
303 | public String getBrand() { | |
304 | return brand; | |
305 | } | |
306 | ||
307 | /** | |
308 | * @param brand | |
309 | * the brand to set | |
310 | */ | |
311 | public void setBrand(String brand) { | |
312 | this.brand = brand; | |
313 | } | |
314 | ||
315 | /** | |
316 | * @return the prid_time | |
317 | */ | |
318 | public String getPid_time() { | |
319 | return pid_time; | |
320 | } | |
321 | ||
322 | /** | |
323 | * @return the cpu | |
324 | */ | |
325 | public Long getCpu() { | |
326 | return cpu; | |
327 | } | |
328 | ||
329 | /** | |
330 | * @param cpu | |
331 | * the cpu to set | |
332 | */ | |
333 | public void setCpu(Long cpu) { | |
334 | this.cpu = cpu; | |
335 | } | |
336 | ||
337 | /** | |
338 | * @return the current_function | |
339 | */ | |
340 | public Long getCurrent_function() { | |
341 | return current_function; | |
342 | } | |
343 | ||
344 | /** | |
345 | * @param currentFunction | |
346 | * the current_function to set | |
347 | */ | |
348 | public void setCurrent_function(Long currentFunction) { | |
349 | current_function = currentFunction; | |
350 | } | |
351 | ||
352 | /** | |
353 | * @return the target_pid | |
354 | */ | |
355 | public Long getTarget_pid() { | |
356 | return target_pid; | |
357 | } | |
358 | ||
359 | /** | |
360 | * @param targetPid | |
361 | * the target_pid to set | |
362 | */ | |
363 | public void setTarget_pid(Long targetPid) { | |
364 | target_pid = targetPid; | |
365 | } | |
5d10d135 | 366 | |
5d10d135 ASL |
367 | /** |
368 | * @return the free_events | |
369 | */ | |
370 | public Long getFree_events() { | |
371 | return free_events; | |
372 | } | |
373 | ||
374 | /** | |
375 | * @param freeEvents | |
376 | * the free_events to set | |
377 | */ | |
378 | public void setFree_events(Long freeEvents) { | |
379 | free_events = freeEvents; | |
380 | } | |
381 | ||
382 | /** | |
383 | * increment the nuber of free events | |
384 | */ | |
385 | public void incrementFree_events() { | |
386 | ++free_events; | |
387 | } | |
388 | ||
389 | /** | |
390 | * @return the state | |
391 | */ | |
392 | public LttngExecutionState getState() { | |
393 | return state; | |
394 | } | |
395 | ||
396 | /** | |
397 | * @param state | |
398 | * the state to set | |
399 | */ | |
400 | public void setState(LttngExecutionState state) { | |
401 | this.state = state; | |
402 | } | |
403 | ||
404 | /** | |
405 | * @return the type | |
406 | */ | |
407 | public StateStrings.ProcessType getType() { | |
408 | return type; | |
409 | } | |
410 | ||
411 | /** | |
412 | * @param type | |
413 | * the type to set | |
414 | */ | |
415 | public void setType(StateStrings.ProcessType type) { | |
416 | this.type = type; | |
417 | } | |
418 | ||
419 | /** | |
420 | * @return the userTrace | |
421 | */ | |
422 | public String getUserTrace() { | |
423 | return userTrace; | |
424 | } | |
425 | ||
426 | /** | |
427 | * @param userTrace | |
428 | * the userTrace to set | |
429 | */ | |
430 | public void setUserTrace(String userTrace) { | |
431 | this.userTrace = userTrace; | |
432 | } | |
433 | ||
434 | ||
435 | public void clearUserStack() { | |
436 | user_stack.clear(); | |
437 | } | |
438 | ||
439 | public void pushToUserStack(Long newState) { | |
440 | user_stack.push(newState); | |
441 | } | |
442 | ||
443 | public Long popFromUserStack() { | |
444 | if (user_stack.size() <= 1) { | |
445 | TraceDebug.debug("Removing last item from user stack is not allowed! (popFromUserStack)"); | |
446 | return null; | |
447 | } | |
448 | else { | |
449 | return user_stack.pop(); | |
450 | } | |
451 | } | |
452 | ||
453 | public Long peekFromUserStack() { | |
454 | return user_stack.peek(); | |
455 | } | |
456 | ||
457 | ||
458 | ||
459 | public void clearExecutionStack() { | |
460 | execution_stack.clear(); | |
461 | } | |
462 | ||
463 | public void pushToExecutionStack(LttngExecutionState newState) { | |
464 | execution_stack.push(newState); | |
5d10d135 ASL |
465 | } |
466 | ||
467 | public LttngExecutionState popFromExecutionStack() { | |
468 | if (execution_stack.size() <= 1) { | |
58c60db3 | 469 | TraceDebug.debug("Removing last item from execution stack is not allowed! (popFromExecutionStack)"); |
5d10d135 ASL |
470 | return null; |
471 | } | |
472 | else { | |
58c60db3 | 473 | return execution_stack.pop(); |
5d10d135 ASL |
474 | } |
475 | } | |
476 | ||
477 | public LttngExecutionState peekFromExecutionStack() { | |
478 | return execution_stack.peek(); | |
479 | } | |
480 | ||
481 | public LttngExecutionState getFirstElementFromExecutionStack() { | |
482 | return execution_stack.firstElement(); | |
483 | } | |
58c60db3 FC |
484 | |
485 | /* | |
486 | * MAIN : For testing only! | |
487 | */ | |
488 | public static void main(String[] args) { | |
489 | ||
490 | // !!! TESTING CLONE HERE !!! | |
491 | ||
492 | // *** New object with some args set to "123" | |
493 | LttngProcessState joie = new LttngProcessState(new TmfTimestamp(123L, (byte) -9)); | |
494 | ||
495 | // Stack not empty by default?? | |
496 | System.out.println("Emptying stack... Trashing empty instance of : " + joie.popFromExecutionStack() ); | |
497 | ||
498 | joie.setCpu(123L); | |
499 | joie.setName("123"); | |
500 | ||
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)); | |
505 | ||
506 | // Print testEx1 reference | |
507 | System.out.println("testEx1 reference : " + testEx1); | |
508 | ||
509 | joie.pushToExecutionStack(testEx1); | |
510 | joie.pushToUserStack(123L); | |
511 | ||
512 | ||
513 | ||
514 | // *** New object cloned from the first one | |
515 | LttngProcessState joie2 = (LttngProcessState)joie.clone(); | |
516 | ||
517 | ||
518 | // *** Modification of the FIRST object : Everything to "456" | |
519 | joie.setCpu(456L); | |
520 | joie.setName("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)); | |
524 | ||
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); | |
530 | ||
531 | ||
532 | // *** TEST : Everything should be "123L" stil | |
533 | System.out.println("123 == " + joie2.getCpu() ); | |
534 | System.out.println("123 == " + joie2.getName() ); | |
535 | ||
536 | LttngExecutionState newtestEx1 = joie2.popFromExecutionStack(); | |
537 | // Print newtestEx1 reference | |
538 | System.out.println("testEx1 reference : " + newtestEx1); | |
539 | ||
540 | System.out.println("123 == " + newtestEx1.getCum_cpu_time() ); | |
541 | System.out.println("123 == " + joie2.popFromUserStack() ); | |
542 | ||
543 | // *** LAST TEST : The joie2 stack should be empty, only joie1 stack contains more than 1 object | |
544 | try { | |
545 | System.out.println("123 == " + joie2.popFromExecutionStack().getCum_cpu_time() ); | |
546 | } | |
547 | catch ( Exception e) { | |
548 | System.out.println("All fine"); | |
549 | } | |
550 | } | |
551 | ||
5d10d135 | 552 | } |