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; | |
21 | ||
22 | /** | |
23 | * <b>LttngProcessState</b> | |
24 | * | |
25 | * @author alvaro | |
26 | * | |
27 | */ | |
28 | public class LttngProcessState implements Cloneable { | |
29 | // ======================================================================== | |
30 | // Data | |
31 | // ======================================================================= | |
32 | private Long cpu = null; | |
33 | private Long pid = null; | |
34 | private Long tgid = null; | |
35 | private String name = null; | |
28b94d61 | 36 | private Long creation_time = null; |
5d10d135 ASL |
37 | private String brand = null; |
38 | private StateStrings.ProcessType type = null; | |
39 | private Long current_function = null; | |
40 | private Long ppid = null; | |
28b94d61 | 41 | private Long insertion_time = null; |
5d10d135 ASL |
42 | private String pid_time = null; |
43 | private Long free_events = null; | |
44 | private LttngExecutionState state = null; // top of stack | |
45 | private Stack<LttngExecutionState> execution_stack = new Stack<LttngExecutionState>(); | |
46 | private Stack<Long> user_stack = new Stack<Long>(); // user space | |
47 | ||
48 | private String userTrace = null; /* Associated file trace */ | |
49 | private Long target_pid = null; /* target PID of the current event. */ | |
2211df66 FC |
50 | private String trace_id = null; |
51 | ||
5d10d135 ASL |
52 | // ======================================================================== |
53 | // Constructor | |
54 | // ======================================================================= | |
28b94d61 | 55 | public LttngProcessState(Long startTime, String traceId) { |
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; | |
ba1bc132 | 61 | this.trace_id = traceId; |
5d10d135 ASL |
62 | init(); |
63 | } | |
64 | ||
65 | public LttngProcessState(Long cpu, Long pid, Long tgid, | |
28b94d61 | 66 | String name, Long startTime, String traceId) { |
5d10d135 ASL |
67 | this.cpu = cpu; |
68 | this.pid = pid; | |
69 | this.tgid = tgid; | |
70 | this.name = name; | |
71 | this.insertion_time = startTime; | |
2211df66 | 72 | this.trace_id = traceId; |
5d10d135 ASL |
73 | init(); |
74 | } | |
75 | ||
76 | // ======================================================================== | |
77 | // Methods | |
78 | // ======================================================================= | |
79 | private void init() { | |
80 | this.brand = StateStrings.LTTV_STATE_UNBRANDED; | |
81 | this.type = StateStrings.ProcessType.LTTV_STATE_USER_THREAD; | |
82 | this.current_function = 0L; | |
83 | this.ppid = 0L; | |
28b94d61 | 84 | this.creation_time = 0L; |
5d10d135 ASL |
85 | this.free_events = 0L; |
86 | ||
63eecb47 | 87 | // Initialise stack |
5d10d135 | 88 | LttngExecutionState es = new LttngExecutionState(); |
63eecb47 | 89 | es.setExec_mode(ExecutionMode.LTTV_STATE_USER_MODE); |
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); | |
63eecb47 FC |
96 | |
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); | |
100 | es | |
101 | .setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE | |
102 | .getInName()); | |
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); | |
5d10d135 ASL |
108 | |
109 | // point state to the top of the stack | |
110 | this.state = es; | |
111 | } | |
112 | ||
cc6eec3e | 113 | @Override |
5d10d135 ASL |
114 | @SuppressWarnings("unchecked") |
115 | public LttngProcessState clone() { | |
116 | LttngProcessState newState = null; | |
117 | ||
118 | try { | |
119 | newState = (LttngProcessState)super.clone(); | |
120 | ||
121 | // *** IMPORTANT *** | |
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; | |
2211df66 | 137 | newState.trace_id = this.trace_id; |
28b94d61 FC |
138 | newState.creation_time = this.creation_time; |
139 | newState.insertion_time = this.insertion_time; | |
5d10d135 ASL |
140 | |
141 | // Call clone on our own object is safe as Long it implements Clonable | |
142 | newState.state = (LttngExecutionState)this.state.clone(); | |
143 | ||
144 | // Clone should work correctly for all stack object that contain basic java object (String, Long, etc...) | |
145 | newState.user_stack = (Stack<Long>)this.user_stack.clone(); | |
146 | ||
147 | ||
148 | // This is worst case : Stack that contain user defined object. We have to unstack it and clone every object in a new stack! | |
149 | // Why does java does not call clone() for every object in the stack it clone? It would probably be too useful... | |
150 | newState.execution_stack = new Stack<LttngExecutionState>(); | |
151 | ||
152 | // Work stack we will use to "pop" item | |
153 | Stack<LttngExecutionState> tmpStack = new Stack<LttngExecutionState>(); | |
154 | ||
155 | // First, we pop every ExecutionState, and insert a CLONED copy into our new cloned stack | |
156 | while ( this.execution_stack.empty() == false ) { | |
157 | // Save a copy of the original reference | |
158 | tmpStack.push(this.execution_stack.peek()); | |
159 | // Push a CLONED copy into the new stack while poping it from the original stack | |
160 | newState.execution_stack.push( this.execution_stack.pop().clone() ); | |
161 | } | |
162 | ||
163 | // Second, we reinsert back our content into the original stack | |
164 | while ( tmpStack.empty() == false ) { | |
165 | // Pop the cloned copy and push it back into the original stack | |
166 | this.execution_stack.push( tmpStack.pop() ); | |
167 | } | |
168 | } | |
169 | catch ( CloneNotSupportedException e ) { | |
170 | System.out.println("Cloning failed with : " + e.getMessage() ); | |
171 | } | |
172 | ||
173 | return newState; | |
174 | } | |
175 | ||
176 | ||
177 | // ======================================================================== | |
178 | // Methods | |
179 | // ======================================================================= | |
180 | /** | |
181 | * @return the pid | |
182 | */ | |
183 | public Long getPid() { | |
184 | return pid; | |
185 | } | |
186 | ||
187 | /** | |
188 | * @param pid | |
189 | * the pid to set | |
190 | */ | |
191 | public void setPid(Long pid) { | |
192 | this.pid = pid; | |
193 | } | |
194 | ||
195 | /** | |
196 | * @return the tgid | |
197 | */ | |
198 | public Long getTgid() { | |
199 | return tgid; | |
200 | } | |
201 | ||
202 | /** | |
203 | * @param tgid | |
204 | * the tgid to set | |
205 | */ | |
206 | public void setTgid(Long tgid) { | |
207 | this.tgid = tgid; | |
208 | } | |
209 | ||
210 | /** | |
211 | * @return the ppid | |
212 | */ | |
213 | public Long getPpid() { | |
214 | return ppid; | |
215 | } | |
216 | ||
217 | /** | |
218 | * @param ppid | |
219 | * the ppid to set | |
220 | */ | |
221 | public void setPpid(Long ppid) { | |
222 | this.ppid = ppid; | |
223 | } | |
224 | ||
225 | /** | |
226 | * <p> | |
227 | * When the parent pid is known, the creation time is also known and | |
228 | * requires update | |
229 | * </p> | |
230 | * | |
231 | * @param ppid | |
232 | * the ppid to set | |
233 | */ | |
28b94d61 | 234 | public void setPpid(Long ppid, Long creationTime) { |
5d10d135 ASL |
235 | if (ppid != null) { |
236 | this.ppid = ppid; | |
237 | } | |
238 | ||
239 | if (creationTime != null) { | |
240 | setCreation_time(creationTime); | |
241 | } | |
242 | } | |
243 | ||
244 | /** | |
245 | * @return the creation_time | |
246 | */ | |
28b94d61 | 247 | public Long getCreation_time() { |
5d10d135 ASL |
248 | return creation_time; |
249 | } | |
250 | ||
251 | /** | |
252 | * @param creationTime | |
253 | * the creation_time to set | |
254 | */ | |
28b94d61 | 255 | public void setCreation_time(Long creationTime) { |
5d10d135 ASL |
256 | if ( (creationTime != null) && (pid != null) ) { |
257 | creation_time = creationTime; | |
258 | StringBuilder sb = new StringBuilder(this.pid.toString() + "-" | |
259 | + creationTime.toString()); | |
260 | this.pid_time = sb.toString(); | |
261 | } | |
262 | } | |
263 | ||
264 | /** | |
265 | * @return the insertion_time | |
266 | */ | |
28b94d61 | 267 | public Long getInsertion_time() { |
5d10d135 ASL |
268 | return insertion_time; |
269 | } | |
270 | ||
271 | /** | |
272 | * @param insertionTime | |
273 | * the insertion_time to set | |
274 | */ | |
28b94d61 | 275 | public void setInsertion_time(Long insertionTime) { |
5d10d135 ASL |
276 | insertion_time = insertionTime; |
277 | } | |
278 | ||
279 | /** | |
280 | * @return the name | |
281 | */ | |
282 | public String getName() { | |
283 | return name; | |
284 | } | |
285 | ||
286 | /** | |
287 | * @param name | |
288 | * the name to set | |
289 | */ | |
290 | public void setName(String name) { | |
291 | this.name = name; | |
292 | } | |
293 | ||
294 | /** | |
295 | * @return the brand | |
296 | */ | |
297 | public String getBrand() { | |
298 | return brand; | |
299 | } | |
300 | ||
301 | /** | |
302 | * @param brand | |
303 | * the brand to set | |
304 | */ | |
305 | public void setBrand(String brand) { | |
306 | this.brand = brand; | |
307 | } | |
308 | ||
309 | /** | |
310 | * @return the prid_time | |
311 | */ | |
312 | public String getPid_time() { | |
313 | return pid_time; | |
314 | } | |
315 | ||
316 | /** | |
317 | * @return the cpu | |
318 | */ | |
319 | public Long getCpu() { | |
320 | return cpu; | |
321 | } | |
322 | ||
323 | /** | |
324 | * @param cpu | |
325 | * the cpu to set | |
326 | */ | |
327 | public void setCpu(Long cpu) { | |
328 | this.cpu = cpu; | |
329 | } | |
330 | ||
331 | /** | |
332 | * @return the current_function | |
333 | */ | |
334 | public Long getCurrent_function() { | |
335 | return current_function; | |
336 | } | |
337 | ||
338 | /** | |
339 | * @param currentFunction | |
340 | * the current_function to set | |
341 | */ | |
342 | public void setCurrent_function(Long currentFunction) { | |
343 | current_function = currentFunction; | |
344 | } | |
345 | ||
346 | /** | |
347 | * @return the target_pid | |
348 | */ | |
349 | public Long getTarget_pid() { | |
350 | return target_pid; | |
351 | } | |
352 | ||
353 | /** | |
354 | * @param targetPid | |
355 | * the target_pid to set | |
356 | */ | |
357 | public void setTarget_pid(Long targetPid) { | |
358 | target_pid = targetPid; | |
359 | } | |
2211df66 FC |
360 | |
361 | public String getTrace_id() { | |
362 | return trace_id; | |
363 | } | |
5d10d135 | 364 | |
2211df66 FC |
365 | public void setTrace_id(String traceId) { |
366 | trace_id = traceId; | |
367 | } | |
368 | ||
5d10d135 ASL |
369 | /** |
370 | * @return the free_events | |
371 | */ | |
372 | public Long getFree_events() { | |
373 | return free_events; | |
374 | } | |
375 | ||
376 | /** | |
377 | * @param freeEvents | |
378 | * the free_events to set | |
379 | */ | |
380 | public void setFree_events(Long freeEvents) { | |
381 | free_events = freeEvents; | |
382 | } | |
383 | ||
384 | /** | |
385 | * increment the nuber of free events | |
386 | */ | |
387 | public void incrementFree_events() { | |
388 | ++free_events; | |
389 | } | |
390 | ||
391 | /** | |
392 | * @return the state | |
393 | */ | |
394 | public LttngExecutionState getState() { | |
395 | return state; | |
396 | } | |
397 | ||
398 | /** | |
399 | * @param state | |
400 | * the state to set | |
401 | */ | |
402 | public void setState(LttngExecutionState state) { | |
403 | this.state = state; | |
404 | } | |
405 | ||
406 | /** | |
407 | * @return the type | |
408 | */ | |
409 | public StateStrings.ProcessType getType() { | |
410 | return type; | |
411 | } | |
412 | ||
413 | /** | |
414 | * @param type | |
415 | * the type to set | |
416 | */ | |
417 | public void setType(StateStrings.ProcessType type) { | |
418 | this.type = type; | |
419 | } | |
420 | ||
421 | /** | |
422 | * @return the userTrace | |
423 | */ | |
424 | public String getUserTrace() { | |
425 | return userTrace; | |
426 | } | |
427 | ||
428 | /** | |
429 | * @param userTrace | |
430 | * the userTrace to set | |
431 | */ | |
432 | public void setUserTrace(String userTrace) { | |
433 | this.userTrace = userTrace; | |
434 | } | |
435 | ||
436 | ||
437 | public void clearUserStack() { | |
438 | user_stack.clear(); | |
439 | } | |
440 | ||
441 | public void pushToUserStack(Long newState) { | |
442 | user_stack.push(newState); | |
443 | } | |
444 | ||
445 | public Long popFromUserStack() { | |
446 | if (user_stack.size() <= 1) { | |
447 | TraceDebug.debug("Removing last item from user stack is not allowed! (popFromUserStack)"); | |
448 | return null; | |
449 | } | |
450 | else { | |
451 | return user_stack.pop(); | |
452 | } | |
453 | } | |
454 | ||
455 | public Long peekFromUserStack() { | |
456 | return user_stack.peek(); | |
457 | } | |
458 | ||
459 | ||
460 | ||
461 | public void clearExecutionStack() { | |
462 | execution_stack.clear(); | |
463 | } | |
464 | ||
465 | public void pushToExecutionStack(LttngExecutionState newState) { | |
466 | execution_stack.push(newState); | |
63eecb47 | 467 | setState(newState); |
5d10d135 ASL |
468 | } |
469 | ||
470 | public LttngExecutionState popFromExecutionStack() { | |
471 | if (execution_stack.size() <= 1) { | |
2211df66 | 472 | TraceDebug.debug("Removing last item from execution stack is not allowed! (popFromExecutionStack)"); |
5d10d135 ASL |
473 | return null; |
474 | } | |
475 | else { | |
63eecb47 FC |
476 | LttngExecutionState popedState = execution_stack.pop(); |
477 | // adjust current state to the new top | |
478 | setState(peekFromExecutionStack()); | |
479 | return popedState; | |
5d10d135 ASL |
480 | } |
481 | } | |
482 | ||
483 | public LttngExecutionState peekFromExecutionStack() { | |
484 | return execution_stack.peek(); | |
485 | } | |
486 | ||
487 | public LttngExecutionState getFirstElementFromExecutionStack() { | |
488 | return execution_stack.firstElement(); | |
489 | } | |
490 | } |