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