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