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.evProcessor.state; | |
13 | ||
5d10d135 ASL |
14 | import org.eclipse.linuxtools.lttng.TraceDebug; |
15 | import org.eclipse.linuxtools.lttng.event.LttngEvent; | |
16 | import org.eclipse.linuxtools.lttng.state.StateStrings; | |
63eecb47 | 17 | import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode; |
5d10d135 ASL |
18 | import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode; |
19 | import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus; | |
8827c197 | 20 | import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor; |
5d10d135 ASL |
21 | import org.eclipse.linuxtools.lttng.state.model.LTTngCPUState; |
22 | import org.eclipse.linuxtools.lttng.state.model.LttngBdevState; | |
23 | import org.eclipse.linuxtools.lttng.state.model.LttngExecutionState; | |
24 | import org.eclipse.linuxtools.lttng.state.model.LttngIRQState; | |
25 | import org.eclipse.linuxtools.lttng.state.model.LttngProcessState; | |
26 | import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; | |
27 | import org.eclipse.linuxtools.tmf.event.TmfTimestamp; | |
28 | ||
63eecb47 | 29 | public abstract class AbsStateUpdate extends AbsStateProcessing implements |
8827c197 | 30 | ILttngEventProcessor { |
5d10d135 ASL |
31 | |
32 | // ======================================================================== | |
33 | // Data | |
34 | // ======================================================================= | |
35 | protected static final Long ANY_CPU = 0L; | |
36 | ||
37 | // ======================================================================== | |
38 | // push and pop from stack | |
39 | // ======================================================================= | |
40 | protected void push_state(Long cpu, StateStrings.ExecutionMode execMode, | |
b12f4544 | 41 | String submode, int subModeId, TmfTimestamp eventTime, LttngTraceState traceSt) { |
5d10d135 ASL |
42 | |
43 | LttngProcessState process = traceSt.getRunning_process().get(cpu); | |
44 | LttngExecutionState exe_state = new LttngExecutionState(); | |
45 | exe_state.setExec_mode(execMode); | |
46 | exe_state.setExec_submode(submode); | |
b12f4544 | 47 | exe_state.setExec_submode_id(subModeId); |
28b94d61 FC |
48 | exe_state.setEntry_Time(eventTime.getValue()); |
49 | exe_state.setChange_Time(eventTime.getValue()); | |
5d10d135 | 50 | exe_state.setCum_cpu_time(0L); |
550d787e FC |
51 | // if (process != null) |
52 | exe_state.setProc_status(process.getState().getProc_status()); | |
5d10d135 ASL |
53 | process.pushToExecutionStack(exe_state); |
54 | } | |
55 | ||
56 | protected void pop_state(Long cpu, StateStrings.ExecutionMode execMode, | |
57 | LttngTraceState traceSt, TmfTimestamp eventTime) { | |
58 | ||
59 | LttngProcessState process = traceSt.getRunning_process().get(cpu); | |
60 | ||
61 | if (!process.getState().getExec_mode().equals(execMode)) { | |
62 | // Different execution mode | |
3b38ea61 FC |
63 | TraceDebug.debug("Different Execution Mode type \n\tTime:" //$NON-NLS-1$ |
64 | + eventTime.toString() + "\n\tprocess state has: \n\t" //$NON-NLS-1$ | |
5d10d135 | 65 | + process.getState().getExec_mode().toString() |
3b38ea61 | 66 | + "\n\twhen pop_int is:\n\t" + execMode.toString()); //$NON-NLS-1$ |
5d10d135 ASL |
67 | return; |
68 | } | |
69 | ||
63eecb47 | 70 | //The process state is updated within the pop method |
5d10d135 | 71 | process.popFromExecutionStack(); |
28b94d61 | 72 | process.getState().setChange_Time(eventTime.getValue()); |
5d10d135 ASL |
73 | } |
74 | ||
75 | protected void irq_push_mode(LttngIRQState irqst, IRQMode state) { | |
76 | irqst.pushToIrqStack(state); | |
77 | } | |
78 | ||
79 | protected void irq_set_base_mode(LttngIRQState irqst, IRQMode state) { | |
80 | irqst.clearAndSetBaseToIrqStack(state); | |
81 | } | |
82 | ||
83 | protected void irq_pop_mode(LttngIRQState irqst) { | |
84 | irqst.popFromIrqStack(); | |
85 | } | |
86 | ||
87 | protected void cpu_push_mode(LTTngCPUState cpust, StateStrings.CpuMode state) { | |
88 | // The initialization (init) creates a LttngCPUState instance per | |
89 | // available cpu in the system | |
90 | cpust.pushToCpuStack(state); | |
91 | } | |
92 | ||
93 | protected void cpu_pop_mode(LTTngCPUState cpust) { | |
94 | cpust.popFromCpuStack(); | |
95 | } | |
96 | ||
97 | /* clears the stack and sets the state passed as argument */ | |
98 | protected void cpu_set_base_mode(LTTngCPUState cpust, | |
99 | StateStrings.CpuMode state) { | |
100 | cpust.clearAndSetBaseToCpuStack(state); | |
101 | } | |
102 | ||
103 | protected void bdev_pop_mode(LttngBdevState bdevst) { | |
104 | bdevst.popFromBdevStack(); | |
105 | } | |
106 | ||
107 | /** | |
108 | * Push a new received function pointer to the user_stack | |
109 | * | |
110 | * @param traceSt | |
111 | * @param funcptr | |
112 | * @param cpu | |
113 | */ | |
114 | protected void push_function(LttngTraceState traceSt, Long funcptr, Long cpu) { | |
115 | // Get the related process | |
116 | LttngProcessState process = traceSt.getRunning_process().get(cpu); | |
117 | ||
118 | // update stack | |
119 | process.pushToUserStack(funcptr); | |
120 | ||
121 | // update the pointer to the current function on the corresponding | |
122 | // process | |
123 | process.setCurrent_function(funcptr); | |
124 | } | |
125 | ||
126 | protected void pop_function(LttngTraceState traceSt, LttngEvent trcEvent, | |
127 | Long funcptr) { | |
128 | Long cpu = trcEvent.getCpuId(); | |
129 | LttngProcessState process = traceSt.getRunning_process().get(cpu); | |
130 | Long curr_function = process.getCurrent_function(); | |
131 | ||
550d787e | 132 | if (curr_function != null && !curr_function.equals(funcptr)) { |
3b38ea61 FC |
133 | TraceDebug.debug("Different functions: " + funcptr + " current: " //$NON-NLS-1$ //$NON-NLS-2$ |
134 | + curr_function + " time stamp: " //$NON-NLS-1$ | |
5d10d135 ASL |
135 | + trcEvent.getTimestamp().toString()); |
136 | ||
137 | // g_info("Different functions (%lu.%09lu): ignore it\n", | |
138 | // tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec); | |
139 | // g_info("process state has %" PRIu64 " when pop_function is %" | |
140 | // PRIu64 | |
141 | // "\n", | |
142 | // process->current_function, funcptr); | |
143 | // g_info("{ %u, %u, %s, %s, %s }\n", | |
144 | // process->pid, | |
145 | // process->ppid, | |
146 | // g_quark_to_string(process->name), | |
147 | // g_quark_to_string(process->brand), | |
148 | // g_quark_to_string(process->state->s)); | |
149 | return; | |
150 | } | |
151 | ||
152 | process.popFromUserStack(); | |
153 | process.setCurrent_function(process.peekFromUserStack()); | |
154 | } | |
155 | ||
156 | // ======================================================================== | |
157 | // General methods | |
158 | // ======================================================================= | |
159 | // Adaption from MKDEV macro | |
160 | protected Long mkdev(Long major, Long minor) { | |
161 | Long result = null; | |
162 | if (major != null && minor != null) { | |
163 | result = (major << 20) | minor; | |
164 | } | |
165 | return result; | |
166 | } | |
167 | ||
168 | /* | |
169 | * FIXME : this function should be called when we receive an event telling | |
170 | * that release_task has been called in the kernel. In happens generally | |
63eecb47 | 171 | * when the parent waits for its child termination, but may also happen in |
5d10d135 ASL |
172 | * special cases in the child's exit : when the parent ignores its children |
173 | * SIGCCHLD or has the flag SA_NOCLDWAIT. It can also happen when the child | |
174 | * is part of a killed thread group, but isn't the leader. | |
175 | */ | |
176 | protected boolean exit_process(LttngTraceState ts, LttngProcessState process) { | |
177 | /* | |
178 | * Wait for both schedule with exit dead and process free to happen. | |
179 | * They can happen in any order. | |
180 | */ | |
181 | process.incrementFree_events(); | |
182 | if (process.getFree_events() < 2) { | |
183 | return false; | |
184 | } | |
185 | ||
186 | process.clearExecutionStack(); | |
187 | process.clearUserStack(); | |
2211df66 | 188 | ts.removeProcessState(process); |
5d10d135 ASL |
189 | |
190 | return true; | |
191 | } | |
192 | ||
193 | /** | |
194 | * @param traceSt | |
195 | * @param cpu | |
196 | * @param pid | |
197 | * @param tgid | |
198 | * @param timestamp | |
199 | * @return | |
200 | */ | |
201 | protected LttngProcessState create_process(LttngTraceState traceSt, | |
202 | Long cpu, Long pid, Long tgid, final TmfTimestamp timestamp) { | |
203 | LttngProcessState process = create_process(traceSt, cpu, pid, tgid, | |
204 | ProcessStatus.LTTV_STATE_UNNAMED.getInName(), timestamp); | |
205 | return process; | |
206 | } | |
207 | ||
208 | /** | |
209 | * @param traceSt | |
210 | * @param cpu | |
211 | * @param pid | |
212 | * @param tgid | |
213 | * @param name | |
214 | * @param timestamp | |
215 | * @return | |
216 | */ | |
217 | protected LttngProcessState create_process(LttngTraceState traceSt, | |
218 | Long cpu, Long pid, Long tgid, String name, | |
219 | final TmfTimestamp timestamp) { | |
220 | LttngProcessState process; | |
28b94d61 | 221 | process = new LttngProcessState(cpu, pid, tgid, name, timestamp.getValue(), traceSt.getTraceId()); |
2211df66 | 222 | traceSt.addProcessState(process); |
5d10d135 ASL |
223 | return process; |
224 | } | |
225 | ||
63eecb47 FC |
226 | /** |
227 | * @param ts | |
228 | * @param cpu | |
229 | * @param pid | |
230 | * @param timestamp | |
231 | * , Used when a new process is needed | |
232 | * @return | |
233 | */ | |
234 | protected LttngProcessState lttv_state_find_process_or_create( | |
235 | LttngTraceState ts, Long cpu, Long pid, final TmfTimestamp timestamp) { | |
236 | ||
237 | LttngProcessState process = lttv_state_find_process(ts, cpu, pid); | |
238 | /* Put ltt_time_zero creation time for non existing processes */ | |
239 | if (process == null) { | |
240 | process = create_process(ts, cpu, pid, 0L, timestamp); | |
241 | // leave only one entry in the execution stack | |
242 | process.popFromExecutionStack(); | |
243 | LttngExecutionState es = process.getState(); | |
244 | es.setExec_mode(ExecutionMode.LTTV_STATE_MODE_UNKNOWN); | |
245 | es.setProc_status(ProcessStatus.LTTV_STATE_UNNAMED); | |
246 | } | |
247 | ||
248 | return process; | |
249 | } | |
250 | ||
5d10d135 | 251 | } |