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 | ||
58c60db3 | 14 | import java.util.ArrayList; |
5d10d135 ASL |
15 | import java.util.HashMap; |
16 | import java.util.Iterator; | |
58c60db3 | 17 | import java.util.List; |
5d10d135 ASL |
18 | import java.util.Map; |
19 | ||
5d10d135 ASL |
20 | import org.eclipse.linuxtools.lttng.state.LttngStateException; |
21 | import org.eclipse.linuxtools.lttng.state.StateStrings; | |
22 | import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode; | |
23 | import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionSubMode; | |
24 | import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode; | |
25 | import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus; | |
5d10d135 | 26 | import org.eclipse.linuxtools.tmf.event.TmfTimeRange; |
58c60db3 | 27 | import org.eclipse.linuxtools.tmf.event.TmfTimestamp; |
5d10d135 ASL |
28 | |
29 | /** | |
30 | * <b><u>LttngTraceState</u></b> | |
31 | * <p> | |
32 | * | |
33 | */ | |
34 | /** | |
35 | * @author alvaro | |
36 | * | |
37 | */ | |
38 | public class LttngTraceState implements Cloneable { | |
39 | // ======================================================================== | |
40 | // Data | |
41 | // ======================================================================= | |
42 | ||
43 | private Long save_interval = null; | |
44 | ||
58c60db3 | 45 | private TmfTimestamp max_time_state_recomputed_in_seek = null; |
5d10d135 ASL |
46 | private boolean has_precomputed_states = false; |
47 | ||
58c60db3 FC |
48 | // TODO: check if this can be used as a map, but consider that the key |
49 | // shall be composed by Pid, TimeStamp, and CPU, this combination may not | |
50 | // always be available and the cpu value may change over time. | |
51 | private List<LttngProcessState> processes = new ArrayList<LttngProcessState>(); | |
5d10d135 ASL |
52 | |
53 | // by cpu | |
54 | private Map<Long, LttngProcessState> running_process = new HashMap<Long, LttngProcessState>(); | |
55 | ||
56 | // Get state tables | |
57 | private Map<Long, LTTngCPUState> cpu_states = new HashMap<Long, LTTngCPUState>(); | |
58 | private Map<Long, LttngIRQState> irq_states = new HashMap<Long, LttngIRQState>(); | |
59 | private Map<Long, LttngSoftIRQState> soft_irq_states = new HashMap<Long, LttngSoftIRQState>(); | |
60 | private Map<Long, LttngTrapState> trap_states = new HashMap<Long, LttngTrapState>(); | |
61 | private Map<Long, LttngBdevState> bdev_states = new HashMap<Long, LttngBdevState>(); | |
62 | ||
63 | // Get name tables | |
64 | private Map<Long, String> syscall_names = new HashMap<Long, String>(); | |
65 | private Map<Long, String> kprobe_table = new HashMap<Long, String>(); | |
66 | private Map<Long, String> soft_irq_names = new HashMap<Long, String>(); | |
67 | private Map<Long, String> trap_names = new HashMap<Long, String>(); | |
68 | private Map<Long, String> irq_names = new HashMap<Long, String>(); | |
69 | ||
70 | private int nb_events = 0; | |
71 | ||
72 | // reference to input data provider | |
88144d4a | 73 | ILttngStateInputRef inputDataRef = null; |
5d10d135 ASL |
74 | String traceId = ""; |
75 | ||
76 | // ======================================================================== | |
77 | // Constructor | |
78 | // ======================================================================= | |
79 | LttngTraceState() { | |
80 | // Get name tables | |
81 | StateStrings strings = StateStrings.getInstance(); | |
82 | ||
83 | // initialize sycall_names | |
84 | String[] ref_name_table = strings.getSyscallNames(); | |
85 | for (Long i = 0L; i < ref_name_table.length; i++) { | |
86 | syscall_names.put(i, ref_name_table[i.intValue()]); | |
87 | } | |
88 | ||
89 | // trap names | |
90 | ref_name_table = strings.getTrapNames(); | |
91 | for (Long i = 0L; i < ref_name_table.length; i++) { | |
92 | trap_names.put(i, ref_name_table[i.intValue()]); | |
93 | } | |
94 | ||
95 | // irq names | |
96 | ref_name_table = strings.getIrqNames(); | |
97 | for (Long i = 0L; i < ref_name_table.length; i++) { | |
98 | irq_names.put(i, ref_name_table[i.intValue()]); | |
99 | } | |
100 | ||
101 | // softirq names | |
102 | ref_name_table = strings.getSoftIrqNames(); | |
103 | for (Long i = 0L; i < ref_name_table.length; i++) { | |
104 | soft_irq_names.put(i, ref_name_table[i.intValue()]); | |
105 | } | |
106 | } | |
107 | ||
108 | // ======================================================================= | |
109 | // Methods | |
110 | // ======================================================================= | |
cc6eec3e | 111 | @Override |
5d10d135 ASL |
112 | public LttngTraceState clone() { |
113 | LttngTraceState newState = null; | |
114 | ||
115 | try { | |
116 | newState = (LttngTraceState) super.clone(); | |
117 | ||
118 | // *** IMPORTANT *** | |
119 | // Basic type in java are immutable! | |
120 | // Thus, using assignment ("=") on basic type is CORRECT, | |
121 | // but we should ALWAYS use "new" or "clone()" on "non basic" type | |
122 | newState.save_interval = this.save_interval; | |
123 | newState.traceId = this.traceId; | |
124 | ||
125 | // Basic value only need to be assigned while cloning | |
126 | newState.has_precomputed_states = this.has_precomputed_states; | |
127 | newState.nb_events = this.nb_events; | |
58c60db3 FC |
128 | |
129 | // No clonable implemented in TMF, we will use copy constructor | |
130 | // NOTE : we GOT to check for null to avoid crashing on null pointer | |
131 | // here! | |
132 | if (this.max_time_state_recomputed_in_seek != null) { | |
133 | newState.max_time_state_recomputed_in_seek = new TmfTimestamp( | |
134 | this.max_time_state_recomputed_in_seek); | |
135 | } | |
5d10d135 ASL |
136 | |
137 | // Clone should work correctly for all stack object that contain | |
138 | // basic java object (String, Long, etc...) | |
139 | newState.syscall_names = this.syscall_names; | |
140 | newState.kprobe_table = this.kprobe_table; | |
141 | newState.soft_irq_names = this.soft_irq_names; | |
142 | newState.trap_names = this.trap_names; | |
143 | newState.irq_names = this.irq_names; | |
144 | ||
145 | // This reference should never need to be updated, should it? | |
88144d4a | 146 | newState.inputDataRef = this.inputDataRef; |
5d10d135 ASL |
147 | |
148 | // *** We need loop on each ArrayList and HashMap, as java implement | |
149 | // nothing that's remotely near deep copying. | |
150 | // *** TODO *** | |
151 | // In the future, implement something better here... serialization | |
152 | // perhaps? Or copy the array chunk of memory in C? | |
58c60db3 FC |
153 | newState.processes = new ArrayList<LttngProcessState>(); |
154 | for (int pos = 0; pos < this.processes.size(); pos++) { | |
155 | newState.processes.add(this.processes.get(pos).clone()); | |
5d10d135 ASL |
156 | } |
157 | ||
58c60db3 FC |
158 | Iterator<Long> iterator = null; |
159 | Long mapKey = null; | |
160 | ||
5d10d135 | 161 | newState.running_process = new HashMap<Long, LttngProcessState>(); |
58c60db3 FC |
162 | iterator = this.running_process.keySet().iterator(); |
163 | while (iterator.hasNext()) { | |
164 | mapKey = iterator.next(); | |
165 | newState.running_process.put(mapKey, this.running_process.get( | |
166 | mapKey).clone()); | |
5d10d135 ASL |
167 | } |
168 | ||
169 | newState.cpu_states = new HashMap<Long, LTTngCPUState>(); | |
58c60db3 FC |
170 | iterator = this.cpu_states.keySet().iterator(); |
171 | while (iterator.hasNext()) { | |
172 | mapKey = iterator.next(); | |
5d10d135 ASL |
173 | newState.cpu_states.put(mapKey, this.cpu_states.get(mapKey) |
174 | .clone()); | |
175 | } | |
176 | ||
177 | newState.irq_states = new HashMap<Long, LttngIRQState>(); | |
58c60db3 FC |
178 | iterator = this.irq_states.keySet().iterator(); |
179 | while (iterator.hasNext()) { | |
180 | mapKey = iterator.next(); | |
5d10d135 ASL |
181 | newState.irq_states.put(mapKey, this.irq_states.get(mapKey) |
182 | .clone()); | |
183 | } | |
184 | ||
185 | newState.soft_irq_states = new HashMap<Long, LttngSoftIRQState>(); | |
58c60db3 FC |
186 | iterator = this.soft_irq_states.keySet().iterator(); |
187 | while (iterator.hasNext()) { | |
188 | mapKey = iterator.next(); | |
5d10d135 ASL |
189 | newState.soft_irq_states.put(mapKey, this.soft_irq_states.get( |
190 | mapKey).clone()); | |
191 | } | |
192 | ||
193 | newState.trap_states = new HashMap<Long, LttngTrapState>(); | |
58c60db3 FC |
194 | iterator = this.trap_states.keySet().iterator(); |
195 | while (iterator.hasNext()) { | |
196 | mapKey = iterator.next(); | |
5d10d135 ASL |
197 | newState.trap_states.put(mapKey, this.trap_states.get(mapKey) |
198 | .clone()); | |
199 | } | |
200 | ||
201 | newState.bdev_states = new HashMap<Long, LttngBdevState>(); | |
58c60db3 FC |
202 | iterator = this.bdev_states.keySet().iterator(); |
203 | while (iterator.hasNext()) { | |
204 | mapKey = iterator.next(); | |
5d10d135 ASL |
205 | newState.bdev_states.put(mapKey, this.bdev_states.get(mapKey) |
206 | .clone()); | |
207 | } | |
208 | ||
209 | } catch (CloneNotSupportedException e) { | |
210 | System.out.println("Cloning failed with : " + e.getMessage()); | |
211 | } | |
212 | ||
213 | return newState; | |
214 | } | |
215 | ||
88144d4a | 216 | public void init(ILttngStateInputRef inputReference) |
5d10d135 | 217 | throws LttngStateException { |
88144d4a | 218 | if (inputReference == null) { |
5d10d135 ASL |
219 | StringBuilder sb = new StringBuilder( |
220 | "The input provider reference must not be null"); | |
221 | throw new LttngStateException(sb.toString()); | |
222 | } | |
223 | ||
224 | // Save the input data reference | |
88144d4a | 225 | inputDataRef = inputReference; |
5d10d135 ASL |
226 | |
227 | // Save traceid | |
88144d4a | 228 | traceId = inputDataRef.getTraceId(); |
5d10d135 ASL |
229 | |
230 | // max time | |
58c60db3 | 231 | setMax_time_state_recomputed_in_seek(new TmfTimestamp()); |
5d10d135 ASL |
232 | |
233 | // reset cpu_states | |
234 | cpu_states.clear(); | |
235 | ||
236 | // Obtain the total num of available CPUs and initialize the map | |
237 | // to the corresponding size | |
88144d4a | 238 | int numCpus = inputDataRef.getNumberOfCpus(); |
5d10d135 ASL |
239 | for (Long i = 0L; i < numCpus; i++) { |
240 | cpu_states.put(i, new LTTngCPUState()); | |
241 | } | |
242 | ||
243 | // irq states | |
244 | irq_states.clear(); | |
245 | for (Long i = 0L; i < irq_names.size(); i++) { | |
246 | irq_states.put(i, new LttngIRQState()); | |
247 | } | |
248 | ||
249 | // soft irqs | |
250 | soft_irq_states.clear(); | |
251 | for (Long i = 0L; i < soft_irq_names.size(); i++) { | |
252 | soft_irq_states.put(i, new LttngSoftIRQState()); | |
253 | } | |
254 | ||
255 | // traps | |
256 | trap_states.clear(); | |
257 | for (Long i = 0L; i < trap_names.size(); i++) { | |
258 | trap_states.put(i, new LttngTrapState(0L)); | |
259 | } | |
260 | ||
261 | // bdev states | |
262 | bdev_states.clear(); | |
58c60db3 FC |
263 | |
264 | // JniTrace State | |
265 | init_state(numCpus); | |
266 | ||
267 | } | |
268 | ||
269 | public void init_state(int numCpus) { | |
5d10d135 ASL |
270 | processes.clear(); |
271 | ||
272 | nb_events = 0; | |
88144d4a | 273 | TmfTimeRange timeWin = inputDataRef.getTraceTimeWindow(); |
5d10d135 ASL |
274 | |
275 | /* Put the per cpu running_process to beginning state : process 0. */ | |
276 | for (Long i = 0L; i < numCpus; i++) { | |
58c60db3 FC |
277 | LttngProcessState process = new LttngProcessState(timeWin |
278 | .getStartTime()); | |
5d10d135 ASL |
279 | |
280 | /* | |
281 | * We are not sure is it's a kernel thread or normal thread, put the | |
282 | * bottom stack state to unknown | |
283 | */ | |
284 | LttngExecutionState es = process.getFirstElementFromExecutionStack(); | |
285 | process.setState(es); | |
286 | es.setExec_mode(ExecutionMode.LTTV_STATE_MODE_UNKNOWN); | |
287 | es.setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE | |
288 | .getInName()); | |
289 | es.setProc_status(ProcessStatus.LTTV_STATE_UNNAMED); | |
290 | ||
291 | // Reduce from default to only one execution state in the stack | |
292 | process.popFromExecutionStack(); | |
293 | ||
294 | process.setCpu(i); | |
295 | // no associated user trace yet | |
296 | process.setUserTrace(""); | |
297 | // processes.put(i, process); | |
298 | running_process.put(i, process); | |
299 | // reset cpu states | |
300 | LTTngCPUState cpuState = cpu_states.get(i); | |
301 | cpuState.reset(); | |
302 | // Add the new process to the list | |
58c60db3 | 303 | processes.add(process); |
5d10d135 ASL |
304 | } |
305 | ||
306 | // reset irq_states | |
307 | for (Long key : irq_states.keySet()) { | |
308 | LttngIRQState irqState = irq_states.get(key); | |
309 | irqState.clearAndSetBaseToIrqStack(IRQMode.LTTV_IRQ_UNKNOWN); | |
310 | } | |
311 | ||
312 | // reset soft_irq_states | |
313 | for (Long key : soft_irq_states.keySet()) { | |
314 | LttngSoftIRQState softIrqState = soft_irq_states.get(key); | |
315 | softIrqState.reset(); | |
316 | } | |
317 | ||
318 | // reset trap_states | |
319 | for (Long key : trap_states.keySet()) { | |
320 | LttngTrapState trapState = trap_states.get(key); | |
321 | trapState.setRunning(0L); | |
322 | } | |
323 | ||
324 | // reset bdev_states | |
325 | for (Long key : bdev_states.keySet()) { | |
326 | LttngBdevState bdevState = bdev_states.get(key); | |
327 | bdevState.clearBdevStack(); | |
328 | } | |
329 | ||
330 | } | |
331 | ||
332 | public Long getSave_interval() { | |
333 | return save_interval; | |
334 | } | |
335 | ||
336 | public void setSave_interval(Long saveInterval) { | |
337 | save_interval = saveInterval; | |
338 | } | |
339 | ||
340 | /** | |
341 | * @return total number of CPUs registered as read from the Trace | |
342 | */ | |
343 | public int getNumberOfCPUs() { | |
88144d4a | 344 | return inputDataRef.getNumberOfCpus(); |
5d10d135 ASL |
345 | } |
346 | ||
347 | /** | |
348 | * Provide access to input data not necessarily at Trace level | |
349 | * | |
350 | * @return | |
351 | */ | |
88144d4a ASL |
352 | public ILttngStateInputRef getInputDataRef() { |
353 | return inputDataRef; | |
5d10d135 ASL |
354 | } |
355 | ||
58c60db3 | 356 | public TmfTimestamp getMax_time_state_recomputed_in_seek() { |
5d10d135 ASL |
357 | return max_time_state_recomputed_in_seek; |
358 | } | |
359 | ||
360 | public void setMax_time_state_recomputed_in_seek( | |
58c60db3 | 361 | TmfTimestamp maxTimeStateRecomputedInSeek) { |
5d10d135 ASL |
362 | max_time_state_recomputed_in_seek = maxTimeStateRecomputedInSeek; |
363 | } | |
364 | ||
365 | public boolean isHas_precomputed_states() { | |
366 | return has_precomputed_states; | |
367 | } | |
368 | ||
369 | public void setHas_precomputed_states(boolean hasPrecomputedStates) { | |
370 | has_precomputed_states = hasPrecomputedStates; | |
371 | } | |
58c60db3 FC |
372 | |
373 | ||
374 | public List<LttngProcessState> getProcesses() { | |
375 | return processes; | |
376 | } | |
5d10d135 ASL |
377 | |
378 | public Map<Long, LttngProcessState> getRunning_process() { | |
379 | return running_process; | |
380 | } | |
381 | ||
382 | public Map<Long, String> getSyscall_names() { | |
383 | return syscall_names; | |
384 | } | |
385 | ||
386 | public Map<Long, String> getTrap_names() { | |
387 | return trap_names; | |
388 | } | |
389 | ||
390 | public Map<Long, String> getIrq_names() { | |
391 | return irq_names; | |
392 | } | |
393 | ||
394 | public Map<Long, String> getSoft_irq_names() { | |
395 | return soft_irq_names; | |
396 | } | |
397 | ||
398 | public Map<Long, LTTngCPUState> getCpu_states() { | |
399 | return cpu_states; | |
400 | } | |
401 | ||
402 | public Map<Long, LttngIRQState> getIrq_states() { | |
403 | return irq_states; | |
404 | } | |
405 | ||
406 | public Map<Long, LttngSoftIRQState> getSoft_irq_states() { | |
407 | return soft_irq_states; | |
408 | } | |
409 | ||
410 | public Map<Long, LttngTrapState> getTrap_states() { | |
411 | return trap_states; | |
412 | } | |
413 | ||
414 | public Map<Long, LttngBdevState> getBdev_states() { | |
415 | return bdev_states; | |
416 | } | |
417 | ||
418 | public Map<Long, String> getKprobe_table() { | |
419 | return kprobe_table; | |
420 | } | |
421 | ||
422 | /** | |
423 | * @return the traceId | |
424 | */ | |
425 | public String getTraceId() { | |
426 | return traceId; | |
427 | } | |
5d10d135 | 428 | |
5d10d135 | 429 | } |