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 | ||
b12f4544 | 16 | import org.eclipse.linuxtools.lttng.LttngConstants; |
5d10d135 ASL |
17 | import org.eclipse.linuxtools.lttng.TraceDebug; |
18 | import org.eclipse.linuxtools.lttng.state.StateStrings; | |
19 | import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode; | |
20 | import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionSubMode; | |
21 | import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus; | |
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; | |
28b94d61 | 37 | private Long 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; | |
28b94d61 | 42 | private Long 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. */ | |
2211df66 FC |
51 | private String trace_id = null; |
52 | ||
5d10d135 ASL |
53 | // ======================================================================== |
54 | // Constructor | |
55 | // ======================================================================= | |
28b94d61 | 56 | public LttngProcessState(Long startTime, String traceId) { |
5d10d135 ASL |
57 | this.cpu = 0L; |
58 | this.pid = 0L; | |
59 | this.tgid = 0L; | |
60 | this.name = StateStrings.ProcessStatus.LTTV_STATE_UNNAMED.getInName(); | |
61 | this.insertion_time = startTime; | |
ba1bc132 | 62 | this.trace_id = traceId; |
5d10d135 ASL |
63 | init(); |
64 | } | |
65 | ||
66 | public LttngProcessState(Long cpu, Long pid, Long tgid, | |
28b94d61 | 67 | String name, Long startTime, String traceId) { |
5d10d135 ASL |
68 | this.cpu = cpu; |
69 | this.pid = pid; | |
70 | this.tgid = tgid; | |
71 | this.name = name; | |
72 | this.insertion_time = startTime; | |
2211df66 | 73 | this.trace_id = traceId; |
5d10d135 ASL |
74 | init(); |
75 | } | |
76 | ||
77 | // ======================================================================== | |
78 | // Methods | |
79 | // ======================================================================= | |
80 | private void init() { | |
81 | this.brand = StateStrings.LTTV_STATE_UNBRANDED; | |
82 | this.type = StateStrings.ProcessType.LTTV_STATE_USER_THREAD; | |
83 | this.current_function = 0L; | |
84 | this.ppid = 0L; | |
28b94d61 | 85 | this.creation_time = 0L; |
5d10d135 ASL |
86 | this.free_events = 0L; |
87 | ||
63eecb47 | 88 | // Initialise stack |
5d10d135 | 89 | LttngExecutionState es = new LttngExecutionState(); |
63eecb47 | 90 | es.setExec_mode(ExecutionMode.LTTV_STATE_USER_MODE); |
5d10d135 | 91 | es.setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.getInName()); |
b12f4544 FC |
92 | // Note: For statistics performance improvement a integer representation of the submode is used |
93 | // as well as a bit mask is applied! | |
94 | es.setExec_submode_id(StateStrings.ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.ordinal() | | |
95 | LttngConstants.STATS_NONE_ID); | |
5d10d135 ASL |
96 | es.setEntry_Time(this.insertion_time); |
97 | es.setChange_Time(this.insertion_time); | |
98 | es.setCum_cpu_time(0L); | |
99 | es.setProc_status(ProcessStatus.LTTV_STATE_RUN); | |
100 | this.execution_stack.push(es); | |
63eecb47 FC |
101 | |
102 | //This second entry is needed when processes are created via a Fork event. | |
103 | es = new LttngExecutionState(); | |
104 | es.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL); | |
b12f4544 FC |
105 | es.setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.getInName()); |
106 | // Note: For statistics performance improvement a integer representation of the submode is used | |
107 | // as well as a bit mask is applied! | |
108 | es.setExec_submode_id(StateStrings.ExecutionSubMode.LTTV_STATE_SUBMODE_NONE.ordinal() | | |
109 | LttngConstants.STATS_NONE_ID); | |
63eecb47 FC |
110 | es.setEntry_Time(this.insertion_time); |
111 | es.setChange_Time(this.insertion_time); | |
112 | es.setCum_cpu_time(0L); | |
113 | es.setProc_status(ProcessStatus.LTTV_STATE_WAIT_FORK); | |
114 | this.execution_stack.push(es); | |
5d10d135 ASL |
115 | |
116 | // point state to the top of the stack | |
117 | this.state = es; | |
118 | } | |
119 | ||
cc6eec3e | 120 | @Override |
5d10d135 ASL |
121 | @SuppressWarnings("unchecked") |
122 | public LttngProcessState clone() { | |
123 | LttngProcessState newState = null; | |
124 | ||
125 | try { | |
126 | newState = (LttngProcessState)super.clone(); | |
127 | ||
128 | // *** IMPORTANT *** | |
129 | // Basic type in java are immutable! | |
130 | // Thus, using assignment ("=") on basic type is CORRECT, | |
131 | // but we should ALWAYS use "new" or "clone()" on "non basic" type | |
132 | newState.cpu = this.cpu; | |
133 | newState.pid = this.pid; | |
134 | newState.tgid = this.tgid; | |
135 | newState.name = this.name; | |
136 | newState.brand = this.brand; | |
137 | newState.type = this.type; | |
138 | newState.current_function = this.current_function; | |
139 | newState.ppid = this.ppid; | |
140 | newState.pid_time= this.pid_time; | |
141 | newState.free_events = this.free_events; | |
142 | newState.userTrace = this.userTrace; | |
143 | newState.target_pid = this.target_pid; | |
2211df66 | 144 | newState.trace_id = this.trace_id; |
28b94d61 FC |
145 | newState.creation_time = this.creation_time; |
146 | newState.insertion_time = this.insertion_time; | |
5d10d135 ASL |
147 | |
148 | // Call clone on our own object is safe as Long it implements Clonable | |
149 | newState.state = (LttngExecutionState)this.state.clone(); | |
150 | ||
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(); | |
153 | ||
154 | ||
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>(); | |
158 | ||
159 | // Work stack we will use to "pop" item | |
160 | Stack<LttngExecutionState> tmpStack = new Stack<LttngExecutionState>(); | |
161 | ||
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() ); | |
168 | } | |
169 | ||
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() ); | |
174 | } | |
175 | } | |
176 | catch ( CloneNotSupportedException e ) { | |
9c4eb5f7 | 177 | System.out.println("Cloning failed with : " + e.getMessage() ); //$NON-NLS-1$ |
5d10d135 ASL |
178 | } |
179 | ||
180 | return newState; | |
181 | } | |
182 | ||
183 | ||
184 | // ======================================================================== | |
185 | // Methods | |
186 | // ======================================================================= | |
187 | /** | |
188 | * @return the pid | |
189 | */ | |
190 | public Long getPid() { | |
191 | return pid; | |
192 | } | |
193 | ||
194 | /** | |
195 | * @param pid | |
196 | * the pid to set | |
197 | */ | |
198 | public void setPid(Long pid) { | |
199 | this.pid = pid; | |
200 | } | |
201 | ||
202 | /** | |
203 | * @return the tgid | |
204 | */ | |
205 | public Long getTgid() { | |
206 | return tgid; | |
207 | } | |
208 | ||
209 | /** | |
210 | * @param tgid | |
211 | * the tgid to set | |
212 | */ | |
213 | public void setTgid(Long tgid) { | |
214 | this.tgid = tgid; | |
215 | } | |
216 | ||
217 | /** | |
218 | * @return the ppid | |
219 | */ | |
220 | public Long getPpid() { | |
221 | return ppid; | |
222 | } | |
223 | ||
224 | /** | |
225 | * @param ppid | |
226 | * the ppid to set | |
227 | */ | |
228 | public void setPpid(Long ppid) { | |
229 | this.ppid = ppid; | |
230 | } | |
231 | ||
232 | /** | |
233 | * <p> | |
234 | * When the parent pid is known, the creation time is also known and | |
235 | * requires update | |
236 | * </p> | |
237 | * | |
238 | * @param ppid | |
239 | * the ppid to set | |
240 | */ | |
28b94d61 | 241 | public void setPpid(Long ppid, Long creationTime) { |
5d10d135 ASL |
242 | if (ppid != null) { |
243 | this.ppid = ppid; | |
244 | } | |
245 | ||
246 | if (creationTime != null) { | |
247 | setCreation_time(creationTime); | |
248 | } | |
249 | } | |
250 | ||
251 | /** | |
252 | * @return the creation_time | |
253 | */ | |
28b94d61 | 254 | public Long getCreation_time() { |
5d10d135 ASL |
255 | return creation_time; |
256 | } | |
257 | ||
258 | /** | |
259 | * @param creationTime | |
260 | * the creation_time to set | |
261 | */ | |
28b94d61 | 262 | public void setCreation_time(Long creationTime) { |
5d10d135 ASL |
263 | if ( (creationTime != null) && (pid != null) ) { |
264 | creation_time = creationTime; | |
9c4eb5f7 | 265 | StringBuilder sb = new StringBuilder(this.pid.toString() + "-" //$NON-NLS-1$ |
5d10d135 ASL |
266 | + creationTime.toString()); |
267 | this.pid_time = sb.toString(); | |
268 | } | |
269 | } | |
270 | ||
271 | /** | |
272 | * @return the insertion_time | |
273 | */ | |
28b94d61 | 274 | public Long getInsertion_time() { |
5d10d135 ASL |
275 | return insertion_time; |
276 | } | |
277 | ||
278 | /** | |
279 | * @param insertionTime | |
280 | * the insertion_time to set | |
281 | */ | |
28b94d61 | 282 | public void setInsertion_time(Long insertionTime) { |
5d10d135 ASL |
283 | insertion_time = insertionTime; |
284 | } | |
285 | ||
286 | /** | |
287 | * @return the name | |
288 | */ | |
289 | public String getName() { | |
290 | return name; | |
291 | } | |
292 | ||
293 | /** | |
294 | * @param name | |
295 | * the name to set | |
296 | */ | |
297 | public void setName(String name) { | |
298 | this.name = name; | |
299 | } | |
300 | ||
301 | /** | |
302 | * @return the brand | |
303 | */ | |
304 | public String getBrand() { | |
305 | return brand; | |
306 | } | |
307 | ||
308 | /** | |
309 | * @param brand | |
310 | * the brand to set | |
311 | */ | |
312 | public void setBrand(String brand) { | |
313 | this.brand = brand; | |
314 | } | |
315 | ||
316 | /** | |
317 | * @return the prid_time | |
318 | */ | |
319 | public String getPid_time() { | |
320 | return pid_time; | |
321 | } | |
322 | ||
323 | /** | |
324 | * @return the cpu | |
325 | */ | |
326 | public Long getCpu() { | |
327 | return cpu; | |
328 | } | |
329 | ||
330 | /** | |
331 | * @param cpu | |
332 | * the cpu to set | |
333 | */ | |
334 | public void setCpu(Long cpu) { | |
335 | this.cpu = cpu; | |
336 | } | |
337 | ||
338 | /** | |
339 | * @return the current_function | |
340 | */ | |
341 | public Long getCurrent_function() { | |
342 | return current_function; | |
343 | } | |
344 | ||
345 | /** | |
346 | * @param currentFunction | |
347 | * the current_function to set | |
348 | */ | |
349 | public void setCurrent_function(Long currentFunction) { | |
350 | current_function = currentFunction; | |
351 | } | |
352 | ||
353 | /** | |
354 | * @return the target_pid | |
355 | */ | |
356 | public Long getTarget_pid() { | |
357 | return target_pid; | |
358 | } | |
359 | ||
360 | /** | |
361 | * @param targetPid | |
362 | * the target_pid to set | |
363 | */ | |
364 | public void setTarget_pid(Long targetPid) { | |
365 | target_pid = targetPid; | |
366 | } | |
2211df66 FC |
367 | |
368 | public String getTrace_id() { | |
369 | return trace_id; | |
370 | } | |
5d10d135 | 371 | |
2211df66 FC |
372 | public void setTrace_id(String traceId) { |
373 | trace_id = traceId; | |
374 | } | |
375 | ||
5d10d135 ASL |
376 | /** |
377 | * @return the free_events | |
378 | */ | |
379 | public Long getFree_events() { | |
380 | return free_events; | |
381 | } | |
382 | ||
383 | /** | |
384 | * @param freeEvents | |
385 | * the free_events to set | |
386 | */ | |
387 | public void setFree_events(Long freeEvents) { | |
388 | free_events = freeEvents; | |
389 | } | |
390 | ||
391 | /** | |
392 | * increment the nuber of free events | |
393 | */ | |
394 | public void incrementFree_events() { | |
395 | ++free_events; | |
396 | } | |
397 | ||
398 | /** | |
399 | * @return the state | |
400 | */ | |
401 | public LttngExecutionState getState() { | |
402 | return state; | |
403 | } | |
404 | ||
405 | /** | |
406 | * @param state | |
407 | * the state to set | |
408 | */ | |
409 | public void setState(LttngExecutionState state) { | |
410 | this.state = state; | |
411 | } | |
412 | ||
413 | /** | |
414 | * @return the type | |
415 | */ | |
416 | public StateStrings.ProcessType getType() { | |
417 | return type; | |
418 | } | |
419 | ||
420 | /** | |
421 | * @param type | |
422 | * the type to set | |
423 | */ | |
424 | public void setType(StateStrings.ProcessType type) { | |
425 | this.type = type; | |
426 | } | |
427 | ||
428 | /** | |
429 | * @return the userTrace | |
430 | */ | |
431 | public String getUserTrace() { | |
432 | return userTrace; | |
433 | } | |
434 | ||
435 | /** | |
436 | * @param userTrace | |
437 | * the userTrace to set | |
438 | */ | |
439 | public void setUserTrace(String userTrace) { | |
440 | this.userTrace = userTrace; | |
441 | } | |
442 | ||
443 | ||
444 | public void clearUserStack() { | |
445 | user_stack.clear(); | |
446 | } | |
447 | ||
448 | public void pushToUserStack(Long newState) { | |
449 | user_stack.push(newState); | |
450 | } | |
451 | ||
452 | public Long popFromUserStack() { | |
453 | if (user_stack.size() <= 1) { | |
9c4eb5f7 | 454 | TraceDebug.debug("Removing last item from user stack is not allowed! (popFromUserStack)"); //$NON-NLS-1$ |
5d10d135 ASL |
455 | return null; |
456 | } | |
457 | else { | |
458 | return user_stack.pop(); | |
459 | } | |
460 | } | |
461 | ||
462 | public Long peekFromUserStack() { | |
463 | return user_stack.peek(); | |
464 | } | |
465 | ||
466 | ||
467 | ||
468 | public void clearExecutionStack() { | |
469 | execution_stack.clear(); | |
470 | } | |
471 | ||
472 | public void pushToExecutionStack(LttngExecutionState newState) { | |
473 | execution_stack.push(newState); | |
63eecb47 | 474 | setState(newState); |
5d10d135 ASL |
475 | } |
476 | ||
477 | public LttngExecutionState popFromExecutionStack() { | |
478 | if (execution_stack.size() <= 1) { | |
9c4eb5f7 | 479 | TraceDebug.debug("Removing last item from execution stack is not allowed! (popFromExecutionStack)"); //$NON-NLS-1$ |
5d10d135 ASL |
480 | return null; |
481 | } | |
482 | else { | |
63eecb47 FC |
483 | LttngExecutionState popedState = execution_stack.pop(); |
484 | // adjust current state to the new top | |
485 | setState(peekFromExecutionStack()); | |
486 | return popedState; | |
5d10d135 ASL |
487 | } |
488 | } | |
489 | ||
490 | public LttngExecutionState peekFromExecutionStack() { | |
491 | return execution_stack.peek(); | |
492 | } | |
493 | ||
494 | public LttngExecutionState getFirstElementFromExecutionStack() { | |
495 | return execution_stack.firstElement(); | |
496 | } | |
0c2a2e08 FC |
497 | |
498 | @Override | |
3b38ea61 | 499 | @SuppressWarnings("nls") |
0c2a2e08 FC |
500 | public String toString() { |
501 | String stateSt = state.toString(); | |
502 | String eStackSt = execution_stack.toString(); | |
503 | ||
504 | return "[LttngProcessState: " + "cpu=" + cpu + ",pid=" + pid + ",tgid=" + tgid + ",name=" + name + ",ctime=" + creation_time + | |
505 | ",brand=" + brand + ",type=" + type + ",cfunc=" + current_function + ",ppid=" + ppid + ",itime=" + insertion_time + ",ptime=" + pid_time + | |
506 | ",fevents=" + free_events + ",state=" + stateSt + ",estack=" + eStackSt + ",ustack=" + user_stack + ",utrace=" + userTrace + | |
507 | ",tpid=" + target_pid + ",trace=" + trace_id + "]"; | |
508 | } | |
5d10d135 | 509 | } |