Monster fix: TMF model update + corresponding LTTng adaptations + JUnits
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng / src / org / eclipse / linuxtools / lttng / state / model / LttngTraceState.java
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.HashMap;
15 import java.util.Iterator;
16 import java.util.Map;
17
18 import org.eclipse.linuxtools.lttng.TraceDebug;
19 import org.eclipse.linuxtools.lttng.state.LttngStateException;
20 import org.eclipse.linuxtools.lttng.state.StateStrings;
21 import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode;
22 import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionSubMode;
23 import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode;
24 import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus;
25 import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
26
27 /**
28 * <b><u>LttngTraceState</u></b>
29 * <p>
30 *
31 */
32 /**
33 * @author alvaro
34 *
35 */
36 public class LttngTraceState implements Cloneable {
37 // ========================================================================
38 // Data
39 // =======================================================================
40
41 private Long save_interval = null;
42
43 private Long max_time_state_recomputed_in_seek = null;
44 private boolean has_precomputed_states = false;
45
46 private HashMap<ProcessStateKey, LttngProcessState> processes = new HashMap<ProcessStateKey, LttngProcessState>();
47
48 // by cpu
49 private Map<Long, LttngProcessState> running_process = new HashMap<Long, LttngProcessState>();
50
51 // Get state tables
52 private Map<Long, LTTngCPUState> cpu_states = new HashMap<Long, LTTngCPUState>();
53 private Map<Long, LttngIRQState> irq_states = new HashMap<Long, LttngIRQState>();
54 private Map<Long, LttngSoftIRQState> soft_irq_states = new HashMap<Long, LttngSoftIRQState>();
55 private Map<Long, LttngTrapState> trap_states = new HashMap<Long, LttngTrapState>();
56 private Map<Long, LttngBdevState> bdev_states = new HashMap<Long, LttngBdevState>();
57
58 // Get name tables
59 private Map<Long, String> syscall_names = new HashMap<Long, String>();
60 private Map<Long, String> kprobe_table = new HashMap<Long, String>();
61 private Map<Long, String> soft_irq_names = new HashMap<Long, String>();
62 private Map<Long, String> trap_names = new HashMap<Long, String>();
63 private Map<Long, String> irq_names = new HashMap<Long, String>();
64
65 private int nb_events = 0;
66
67 // reference to input data provider
68 ILttngStateInputRef inputDataRef = null;
69 String traceId = "";
70
71 // ========================================================================
72 // Constructor
73 // =======================================================================
74 LttngTraceState() {
75 // Get name tables
76 StateStrings strings = StateStrings.getInstance();
77
78 // initialize sycall_names
79 String[] ref_name_table = strings.getSyscallNames();
80 for (Long i = 0L; i < ref_name_table.length; i++) {
81 syscall_names.put(i, ref_name_table[i.intValue()]);
82 }
83
84 // trap names
85 ref_name_table = strings.getTrapNames();
86 for (Long i = 0L; i < ref_name_table.length; i++) {
87 trap_names.put(i, ref_name_table[i.intValue()]);
88 }
89
90 // irq names
91 ref_name_table = strings.getIrqNames();
92 for (Long i = 0L; i < ref_name_table.length; i++) {
93 irq_names.put(i, ref_name_table[i.intValue()]);
94 }
95
96 // softirq names
97 ref_name_table = strings.getSoftIrqNames();
98 for (Long i = 0L; i < ref_name_table.length; i++) {
99 soft_irq_names.put(i, ref_name_table[i.intValue()]);
100 }
101 }
102
103 // =======================================================================
104 // Methods
105 // =======================================================================
106 @Override
107 public LttngTraceState clone() {
108 LttngTraceState newState = null;
109
110 try {
111 newState = (LttngTraceState) super.clone();
112
113 // *** IMPORTANT ***
114 // Basic type in java are immutable!
115 // Thus, using assignment ("=") on basic type is CORRECT,
116 // but we should ALWAYS use "new" or "clone()" on "non basic" type
117 newState.save_interval = this.save_interval;
118 newState.traceId = this.traceId;
119
120 // Basic value only need to be assigned while cloning
121 newState.has_precomputed_states = this.has_precomputed_states;
122 newState.nb_events = this.nb_events;
123 newState.max_time_state_recomputed_in_seek = this.max_time_state_recomputed_in_seek;
124
125 // Clone should work correctly for all stack object that contain
126 // basic java object (String, Long, etc...)
127 newState.syscall_names = this.syscall_names;
128 newState.kprobe_table = this.kprobe_table;
129 newState.soft_irq_names = this.soft_irq_names;
130 newState.trap_names = this.trap_names;
131 newState.irq_names = this.irq_names;
132
133 // This reference should never need to be updated, should it?
134 newState.inputDataRef = this.inputDataRef;
135
136 // *** We need loop on each ArrayList and HashMap, as java implement
137 // nothing that's remotely near deep copying.
138 // *** TODO ***
139 // In the future, implement something better here... serialization
140 // perhaps? Or copy the array chunk of memory in C?
141
142 Iterator<Long> iteratorL = null;
143 Iterator<ProcessStateKey> iteratorP = null;
144 Long mapKey = null;
145 ProcessStateKey processKey = null;
146
147 newState.processes = new HashMap<ProcessStateKey, LttngProcessState>();
148 iteratorP = this.processes.keySet().iterator();
149 while (iteratorP.hasNext()) {
150 processKey = iteratorP.next();
151 newState.processes.put(processKey, this.processes.get(processKey).clone());
152 }
153
154 newState.running_process = new HashMap<Long, LttngProcessState>();
155 iteratorL = this.running_process.keySet().iterator();
156 while (iteratorL.hasNext()) {
157 mapKey = iteratorL.next();
158 newState.running_process.put(mapKey, this.running_process.get(mapKey).clone());
159 }
160
161 newState.cpu_states = new HashMap<Long, LTTngCPUState>();
162 iteratorL = this.cpu_states.keySet().iterator();
163 while (iteratorL.hasNext()) {
164 mapKey = iteratorL.next();
165 newState.cpu_states.put(mapKey, this.cpu_states.get(mapKey)
166 .clone());
167 }
168
169 newState.irq_states = new HashMap<Long, LttngIRQState>();
170 iteratorL = this.irq_states.keySet().iterator();
171 while (iteratorL.hasNext()) {
172 mapKey = iteratorL.next();
173 newState.irq_states.put(mapKey, this.irq_states.get(mapKey)
174 .clone());
175 }
176
177 newState.soft_irq_states = new HashMap<Long, LttngSoftIRQState>();
178 iteratorL = this.soft_irq_states.keySet().iterator();
179 while (iteratorL.hasNext()) {
180 mapKey = iteratorL.next();
181 newState.soft_irq_states.put(mapKey, this.soft_irq_states.get(
182 mapKey).clone());
183 }
184
185 newState.trap_states = new HashMap<Long, LttngTrapState>();
186 iteratorL = this.trap_states.keySet().iterator();
187 while (iteratorL.hasNext()) {
188 mapKey = iteratorL.next();
189 newState.trap_states.put(mapKey, this.trap_states.get(mapKey)
190 .clone());
191 }
192
193 newState.bdev_states = new HashMap<Long, LttngBdevState>();
194 iteratorL = this.bdev_states.keySet().iterator();
195 while (iteratorL.hasNext()) {
196 mapKey = iteratorL.next();
197 newState.bdev_states.put(mapKey, this.bdev_states.get(mapKey)
198 .clone());
199 }
200
201 } catch (CloneNotSupportedException e) {
202 System.out.println("Cloning failed with : " + e.getMessage());
203 }
204
205 return newState;
206 }
207
208 public void init(ILttngStateInputRef inputReference)
209 throws LttngStateException {
210 if (inputReference == null) {
211 StringBuilder sb = new StringBuilder(
212 "The input provider reference must not be null");
213 throw new LttngStateException(sb.toString());
214 }
215
216 // Save the input data reference
217 inputDataRef = inputReference;
218
219 // Save traceid
220 traceId = inputDataRef.getTraceId();
221
222 // max time
223 max_time_state_recomputed_in_seek = 0L;
224
225 // reset cpu_states
226 cpu_states.clear();
227
228 // Obtain the total num of available CPUs and initialize the map
229 // to the corresponding size
230 int numCpus = inputDataRef.getNumberOfCpus();
231 for (Long i = 0L; i < numCpus; i++) {
232 cpu_states.put(i, new LTTngCPUState());
233 }
234
235 // irq states
236 irq_states.clear();
237 for (Long i = 0L; i < irq_names.size(); i++) {
238 irq_states.put(i, new LttngIRQState());
239 }
240
241 // soft irqs
242 soft_irq_states.clear();
243 for (Long i = 0L; i < soft_irq_names.size(); i++) {
244 soft_irq_states.put(i, new LttngSoftIRQState());
245 }
246
247 // traps
248 trap_states.clear();
249 for (Long i = 0L; i < trap_names.size(); i++) {
250 trap_states.put(i, new LttngTrapState(0L));
251 }
252
253 // bdev states
254 bdev_states.clear();
255
256 processes.clear();
257
258 nb_events = 0;
259 TmfTimeRange timeWin = inputDataRef.getTraceTimeWindow();
260
261 /* Put the per cpu running_process to beginning state : process 0. */
262 for (Long i = 0L; i < numCpus; i++) {
263 LttngProcessState process = new LttngProcessState(timeWin.getStartTime().getValue(), traceId );
264
265 /*
266 * We are not sure is it's a kernel thread or normal thread, put the
267 * bottom stack state to unknown
268 */
269 LttngExecutionState es = process.getFirstElementFromExecutionStack();
270 process.setState(es);
271 es.setExec_mode(ExecutionMode.LTTV_STATE_MODE_UNKNOWN);
272 es.setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE
273 .getInName());
274 es.setProc_status(ProcessStatus.LTTV_STATE_UNNAMED);
275
276 // Reduce from default to only one execution state in the stack
277 process.popFromExecutionStack();
278
279 process.setCpu(i);
280 // no associated user trace yet
281 process.setUserTrace("");
282 // processes.put(i, process);
283 running_process.put(i, process);
284 // reset cpu states
285 LTTngCPUState cpuState = cpu_states.get(i);
286 cpuState.reset();
287 // Add the new process to the list
288 processes.put(new ProcessStateKey(process), process);
289 }
290
291 // reset irq_states
292 for (Long key : irq_states.keySet()) {
293 LttngIRQState irqState = irq_states.get(key);
294 irqState.clearAndSetBaseToIrqStack(IRQMode.LTTV_IRQ_UNKNOWN);
295 }
296
297 // reset soft_irq_states
298 for (Long key : soft_irq_states.keySet()) {
299 LttngSoftIRQState softIrqState = soft_irq_states.get(key);
300 softIrqState.reset();
301 }
302
303 // reset trap_states
304 for (Long key : trap_states.keySet()) {
305 LttngTrapState trapState = trap_states.get(key);
306 trapState.setRunning(0L);
307 }
308
309 // reset bdev_states
310 for (Long key : bdev_states.keySet()) {
311 LttngBdevState bdevState = bdev_states.get(key);
312 bdevState.clearBdevStack();
313 }
314
315 }
316
317 public Long getSave_interval() {
318 return save_interval;
319 }
320
321 public void setSave_interval(Long saveInterval) {
322 save_interval = saveInterval;
323 }
324
325 /**
326 * @return total number of CPUs registered as read from the Trace
327 */
328 public int getNumberOfCPUs() {
329 return inputDataRef.getNumberOfCpus();
330 }
331
332 /**
333 * Provide access to input data not necessarily at Trace level
334 *
335 * @return
336 */
337 public ILttngStateInputRef getInputDataRef() {
338 return inputDataRef;
339 }
340
341 public Long getMax_time_state_recomputed_in_seek() {
342 return max_time_state_recomputed_in_seek;
343 }
344
345 public void setMax_time_state_recomputed_in_seek(
346 Long maxTimeStateRecomputedInSeek) {
347 max_time_state_recomputed_in_seek = maxTimeStateRecomputedInSeek;
348 }
349
350 public boolean isHas_precomputed_states() {
351 return has_precomputed_states;
352 }
353
354 public void setHas_precomputed_states(boolean hasPrecomputedStates) {
355 has_precomputed_states = hasPrecomputedStates;
356 }
357
358 public Map<Long, LttngProcessState> getRunning_process() {
359 return running_process;
360 }
361
362 public Map<Long, String> getSyscall_names() {
363 return syscall_names;
364 }
365
366 public Map<Long, String> getTrap_names() {
367 return trap_names;
368 }
369
370 public Map<Long, String> getIrq_names() {
371 return irq_names;
372 }
373
374 public Map<Long, String> getSoft_irq_names() {
375 return soft_irq_names;
376 }
377
378 public Map<Long, LTTngCPUState> getCpu_states() {
379 return cpu_states;
380 }
381
382 public Map<Long, LttngIRQState> getIrq_states() {
383 return irq_states;
384 }
385
386 public Map<Long, LttngSoftIRQState> getSoft_irq_states() {
387 return soft_irq_states;
388 }
389
390 public Map<Long, LttngTrapState> getTrap_states() {
391 return trap_states;
392 }
393
394 public Map<Long, LttngBdevState> getBdev_states() {
395 return bdev_states;
396 }
397
398 public Map<Long, String> getKprobe_table() {
399 return kprobe_table;
400 }
401
402 /**
403 * @return the traceId
404 */
405 public String getTraceId() {
406 return traceId;
407 }
408
409 /**
410 * Return an array of Processes
411 *
412 * @return LttngProcessState
413 */
414 public LttngProcessState[] getProcesses() {
415 return processes.values().toArray(new LttngProcessState[processes.size()]);
416 }
417
418 /**
419 * Clear all process state items e.g. when a new experiment is selected
420 */
421 public void clearProcessState() {
422 processes.clear();
423 }
424
425 /**
426 * Interface to add process state.
427 *
428 * @param newProcessState
429 */
430 public void addProcessState(LttngProcessState newProcessState) {
431 if (newProcessState != null) {
432 processes.put( new ProcessStateKey(newProcessState), newProcessState);
433 }
434 }
435
436 /**
437 * Interface to remove process state.
438 *
439 * @param oldProcessState
440 */
441 public void removeProcessState(LttngProcessState oldProcessState) {
442 if (oldProcessState != null) {
443 processes.remove(new ProcessStateKey(oldProcessState));
444 }
445 }
446
447 /**
448 * Search by keys (pid, cpuId and traceId)<p>
449 *
450 * A match is returned if the three arguments received match an entry
451 * Otherwise null is returned
452 *
453 * @param searchedPid The processId (Pid) we are looking for
454 * @param searchedCpuId The cpu Id we are looking for
455 * @param searchedTraceID The traceId (trace name?) we are looking for
456 *
457 * @return LttngProcessState
458 */
459 public LttngProcessState findProcessState(Long searchedPid, Long searchedCpuId, String searchedTraceID) {
460 // Get the TimeRangeEventProcess associated to a key we create here
461 LttngProcessState foundProcess = processes.get( new ProcessStateKey(searchedPid, searchedCpuId, searchedTraceID) );
462
463 return foundProcess;
464 }
465
466
467 }
468
469 class ProcessStateKey {
470 private LttngProcessState valueRef = null;
471
472 private Long pid = null;
473 private Long cpuId = null;
474 private String traceId = null;
475
476 @SuppressWarnings("unused")
477 private ProcessStateKey() { }
478
479 public ProcessStateKey(LttngProcessState newRef) {
480 valueRef = newRef;
481 }
482
483 public ProcessStateKey(Long newPid, Long newCpuId, String newTraceId) {
484 pid = newPid;
485 cpuId = newCpuId;
486 traceId = newTraceId;
487 }
488
489 @Override
490 public boolean equals(Object obj) {
491 boolean isSame = false;
492
493 if ( obj instanceof ProcessStateKey ) {
494 ProcessStateKey procKey = (ProcessStateKey) obj;
495
496 if ( valueRef != null ) {
497 if ( (procKey.getPid().equals(valueRef.getPid()) ) &&
498 (procKey.getTraceId().equals(valueRef.getTrace_id()) ) &&
499 ( (procKey.getCpuId().longValue() == 0L ) || (procKey.getCpuId().equals(valueRef.getCpu())) ) )
500 {
501 isSame = true;
502 }
503 }
504 else {
505 if ( (procKey.getPid().equals(this.pid) ) &&
506 (procKey.getTraceId().equals(this.traceId) ) &&
507 ( (procKey.getCpuId().longValue() == 0L ) || (procKey.getCpuId().equals(this.cpuId)) ) )
508 {
509 isSame = true;
510 }
511 }
512 }
513 else {
514 TraceDebug
515 .debug("ERROR : The received Key is not of the type ProcessStateKey! but "
516 + obj.getClass().toString());
517 }
518
519 return isSame;
520 }
521
522 // *** WARNING : Everything in there work because the check "valueRef != null" is the same for ALL getter
523 // Do NOT change this check without checking.
524 public Long getPid() {
525 if ( valueRef != null ) {
526 return valueRef.getPid();
527 }
528 else {
529 return pid;
530 }
531 }
532
533 public Long getCpuId() {
534 if ( valueRef != null ) {
535 return valueRef.getCpu();
536 }
537 else {
538 return cpuId;
539 }
540 }
541
542 public String getTraceId() {
543 if ( valueRef != null ) {
544 return valueRef.getTrace_id();
545 }
546 else {
547 return traceId;
548 }
549 }
550
551 @Override
552 public int hashCode() {
553 return this.toString().hashCode();
554 }
555
556
557 @Override
558 public String toString() {
559 if ( valueRef != null ) {
560 return (valueRef.getPid().toString() + ":" + valueRef.getCpu().toString() + ":" + valueRef.getTrace_id().toString() );
561 }
562
563 return (pid.toString() + ":" + cpuId.toString() + ":" + traceId.toString());
564 }
565 }
This page took 0.042282 seconds and 5 git commands to generate.