6ea2aecb |
1 | Linux Trace Toolkit |
2 | |
3 | Mathieu Desnoyers 17-05-2004 |
4 | |
5 | |
6 | This document explains how the lttvwindow API could process the event requests |
7 | of the viewers, merging event requests and hook lists to benefit from the fact |
8 | that process_traceset can call multiple hooks for the same event. |
9 | |
10 | First, we will explain the detailed process of event delivery in the current |
11 | framework. We will then study its strengths and weaknesses. |
12 | |
13 | In a second time, a framework where the events requests are dealt by the main |
14 | window with fine granularity will be described. We will then discussed the |
15 | advantages and inconvenients over the first framework. |
16 | |
17 | |
18 | 1. (Actual) Boundaryless event reading |
19 | |
20 | Actually, viewers request events in a time interval from the main window. They |
21 | also specify a (not so) maximum number of events to be delivered. In fact, the |
22 | number of events to read only gives a stop point, from where only events with |
23 | the same timestamp will be delivered. |
24 | |
25 | Viewers register hooks themselves in the traceset context. When merging read |
26 | requests in the main window, all hooks registered by viewers will be called for |
27 | the union of all the read requests, because the main window has no control on |
28 | hook registration. |
29 | |
30 | The main window calls process_traceset on its own for all the intervals |
31 | requested by all the viewers. It must not duplicate a read of the same time |
32 | interval : it could be very hard to filter by viewers. So, in order to achieve |
33 | this, time requests are sorted by start time, and process_traceset is called for |
34 | each time request. We keep the last event time between each read : if the start |
35 | time of the next read is lower than the time reached, we continue the reading |
36 | from the actual position. |
37 | |
38 | We deal with specific number of events requests (infinite end time) by |
39 | garantying that, starting from the time start of the request, at least that |
40 | number of events will be read. As we can't do it efficiently without interacting |
41 | very closely with process_traceset, we always read the specified number of |
42 | events requested starting from the current position when we answer to a request |
43 | based on the number of events. |
44 | |
45 | The viewers have to filter events delivered by traceset reading, because they |
46 | can be asked by another viewer for a totally (or partially) different time |
47 | interval. |
48 | |
49 | |
50 | Weaknesses |
51 | |
52 | - process_middle does not guarantee the number of events read |
53 | |
54 | First of all, a viewer that requests events to process_traceset has no garantee |
55 | that it will get exactly what it asked for. For example, a direct call to |
56 | traceset_middle for a specific number of events will delived _at least_ that |
57 | quantity of events, plus the ones that have the same timestamp that the last one |
58 | has. |
59 | |
60 | - Border effects |
61 | |
62 | Viewer's writers will have to deal with a lot of border effects caused by the |
63 | particularities of the reading by selecting the information. |
64 | |
65 | - Lack of encapsulation |
66 | |
67 | The viewer's writer will have to take into account all the border effects caused |
68 | by the interaction with other modules. This means that event if a viewer works |
69 | well alone or with another viewer, it's possible that new bugs arises when a new |
70 | viewer comes around. |
71 | |
72 | |
73 | - Duplication of the work |
74 | |
75 | Time based filters and counters of events will have to be implemented at the |
76 | viewer's side, which is a duplication of the functionnalities that would |
77 | normally be expected from the tracecontext API. |
78 | |
79 | - Lack of control over the data input |
80 | |
81 | As we expect module's writers to prefer to be as close as possible from the raw |
82 | datas, making them interact with a lower level library that gives them a data |
83 | input that they only control by further filtering of the input is not |
84 | appropriated. We should expect some reluctancy from them about using this API |
85 | because of this lack of control on the input. |
86 | |
87 | - Speed cost |
88 | |
89 | All hooks of all viewers will be called for all the time intervals. So, if we |
90 | have a detailed events list and a control flow view, asking both for different |
91 | time intervals, the detailed events list will have to filter all the events |
92 | delivered originally to the control flow view. This can be a case occuring quite |
93 | often. |
94 | |
95 | |
96 | |
97 | Strengths |
98 | |
99 | - Simple concatenation of time intervals at the main window level. |
100 | |
101 | Having the opportunity of delivering more events than necessary to the viewers |
102 | means that we can concatenate time intervals and number of events requested |
103 | fairly easily, while being hard to determine if some specific cases will be |
104 | wrong by formal methods. |
105 | |
106 | - No duplication of the tracecontext API |
107 | |
108 | Viewers deal directly with the tracecontext API for registering hooks, removing |
109 | a layer of encapsulation. |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | 2. (Proposed) Strict boundaries events reading |
116 | |
117 | The idea behind this method is to provide exactly the events requested by the |
118 | viewers to them, no more, no less. |
119 | |
120 | This method relies on the fact that time based and number based event requests |
121 | are, by nature, totally different and that there is no real interest in merging |
122 | both requests types. |
123 | |
124 | It uses the new API for process traceset suggested in the document |
125 | process_traceset_strict_boundaries.txt. |
126 | |
127 | It also means that the lttvwindow API will have to deal with viewer's hooks. |
128 | Those will not be allowed to add them directly in the context. They will give |
129 | them to the lttvwindow API, along with the time interval or the position and |
130 | number of events. The lttvwindow API will have to take care of adding and |
131 | removing hooks for the different time intervals requested. That means that hooks |
132 | insertion and removal will be done between each traceset processing based on |
133 | the time intervals and event positions related to each hook. We must therefore |
134 | provide a simple interface for hooks passing between the viewers and the main |
135 | window, make them easier to manage from the main window. The new type |
136 | LttvHooksPrio solves this problem. |
137 | |
138 | |
139 | Architecture |
140 | |
141 | Added to the lttvwindow API : |
142 | |
143 | |
144 | - lttvwindow_time_interval_request |
145 | arguments : |
146 | ( MainWindow *main_win, |
147 | TimeWindow time_requested, guint num_events, |
148 | LttvHooksPrio process_traceset_middle, |
149 | LttvHook after_process_traceset, |
150 | gpointer after_process_traceset_data); |
151 | |
152 | - lttvwindow_position_request |
153 | arguments : |
154 | ( MainWindow *main_win, |
155 | LttvTracesetPosition position, guint max_num_events, |
156 | LttvHooksPrio process_traceset_middle, |
157 | LttvHook after_process_traceset, |
158 | gpointer after_process_traceset_data); |
159 | |
160 | |
161 | Internal functions : |
162 | |
163 | - lttvwindow_process_pending_requests |
164 | |
165 | |
166 | |
167 | Implementation |
168 | |
169 | |
170 | - Type LttvHooksPrio |
171 | |
6d917c2c |
172 | see hook_prio.txt |
6ea2aecb |
173 | |
174 | |
175 | - lttvwindow_time_interval_request |
176 | |
177 | It adds the TimeRequest struct to the array of time requests pending and |
178 | registers a pending request for the next g_idle if none is registered. |
179 | |
180 | typedef struct _TimeRequest { |
181 | TimeWindow time_window; |
182 | guint num_events; |
183 | LttvHooksPrio middle_hooks; |
184 | LttvHook after_hook; |
185 | gpointer after_hook_data; |
186 | } TimeRequest; |
187 | |
188 | |
189 | - lttvwindow_position_request |
190 | |
191 | It adds a PositionRequest struct to the array of position requests pending and |
192 | registers a pending request for the next g_idle if none is registered. |
193 | |
194 | typedef struct _PositionRequest { |
195 | LttvTracesetPosition position; |
196 | guint max_num_events; |
197 | LttvHooksPrio middle_hooks; |
198 | LttvHook after_hook; |
199 | gpointer after_hook_data; |
200 | } PositionRequest; |
201 | |
202 | |
203 | |
204 | - lttvwindow_process_pending_requests |
205 | |
206 | This internal function gets called by g_idle, taking care of the pending |
207 | requests. It is responsible for concatenation of time intervals and position |
208 | requests. It does it while it calls process traceset. Here is the detailed |
209 | description of the way it works : |
210 | |
211 | It treats time interval requests and position requests as two different cases. |
212 | So let's start with time interval requests. |
213 | |
214 | - Time interval requests servicing |
215 | |
216 | (1) |
217 | It starts by finding the time interval request with the lowest start time and |
218 | the others with the same start time. It add its (or their) hooks to the context. |
219 | It will use this start time to seek in the traceset. |
220 | |
221 | Then, it searches for what event comes first : the end of one of the time |
222 | request actually added in the context or the start of a time request that is not |
223 | in the context. It uses this value as a end boundary for the first process |
224 | traceset middle call. |
225 | |
226 | After a process traceset middle ends, we check if we have reached the end time |
227 | of any time request. If so, we call the time requests process traceset end hook |
228 | and remove this time request from the context and the array of time requests. If |
229 | the context has no hooks left, that means that we have to jump further in the |
230 | traceset. We then simply have to use the exact routine that we used for (1). |
231 | |
232 | Else, if there are hooks left, that means that we have not finished requesting |
233 | one hook's time interval request yet, but maybe we must add a new time request |
234 | to the hook list of the context. We start back at point (1), except that instead |
235 | of finding the lowest start time, we simply keep the hooks already present in |
236 | the context and add hooks that has their start time with a value equal to the |
237 | last process traceset's end time. |
238 | |
239 | |
240 | - Position requests servicing |
241 | |
242 | As it is nearly impossible to compare two traceset positions without replaying |
243 | part of the traceset reading, which is not very efficient, we consider that the |
244 | performance cost of doing one trace read per request does not justify position |
245 | requests combinations. So, each position request will be serviced independently. |
246 | |
247 | |
248 | |
249 | |
250 | Weaknesses |
251 | |
252 | - Position requests are serviced independently, which may duplicate traceset |
253 | reads. |
254 | |
255 | |
256 | |
257 | Strengths |
258 | |
259 | - Removes the need for filtering of information supplied to the viewers. |
260 | |
261 | - Viewers have a better control on their data input. |
262 | |
263 | - Solves all the weaknesses idenfied in the actual boundaryless traceset |
264 | reading. |