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