@@ -202,16 +202,30 @@ \section{Language grammar}
202
202
% TODO: Make this render a bit nicer.
203
203
% XXX: Is this correct?
204
204
\begin {grammar }
205
- <ProbeSpecifier> ::= <Identifier>
206
- \alt [ <Identifier> ] `:' [ <Identifier> ]
207
- \alt [ <Identifier> ] `:' [ <Identifier> ] `:' [ <Identifier> ]
208
- \alt [ <Identifier> ] `:' [ <Identifier> ] `:'
209
- [ <Identifier> ] `:' [ <Identifier> ]
205
+ <ProbeSymbol> ::= <letter>
206
+ \alt <DecDigitWithZero>
207
+ \alt `*'
208
+ \alt `+'
209
+ \alt `\\ '
210
+ \alt `?'
211
+ \alt `!'
212
+ \alt `['
213
+ \alt `]' ;
214
+
215
+ <ProbeIdent> ::= <ProbeSymbol> \{ <ProbeSymbol> \} ;
216
+
217
+ <ProbeSpecifier> ::= <ProbeIdent>
218
+ \alt [ <ProbeIdent> ] `:' [ <ProbeIdent> ]
219
+ \alt [ <ProbeIdent> ] `:' [ <ProbeIdent> ] `:' [ <ProbeIdent> ]
220
+ \alt [ <ProbeIdent> ] `:' [ <ProbeIdent> ] `:' \newline
221
+ [ <ProbeIdent> ] `:' [ <ProbeIdent> ] ;
210
222
\end {grammar }
211
223
212
224
\noindent
213
225
This provides us with a way to specify the \texttt {provider }, \texttt {module },
214
- \texttt {function } and \texttt {name } of a DTrace probe in D.
226
+ \texttt {function } and \texttt {name } of a DTrace probe in D. The reason symbols
227
+ such as `*' are allowed is because D allows the user to write glob expressions
228
+ much like a Unix shell does.
215
229
216
230
% TODO: Define <Predicate> and <Statements>
217
231
\begin {grammar }
@@ -259,31 +273,72 @@ \section{Safety}
259
273
260
274
\section {Variables }
261
275
\label {sec:d-variables }
262
- DTrace implements three different scopes of variables: global,
263
- thread-local and clause-local. Global variables are visible to every
264
- probe and across all threads, allowing the user to write scripts that
265
- carry state across multiple threads should it be
266
- necessary. Thread-local variables are only visible within a single
267
- software thread, they are represented in source code as prefixed with
268
- \texttt {self-> }. Clause-local variables are implemented on a
269
- per-thread basis and are identified by the prefix
270
- \texttt {this-> }. Clause-local variables should be initialised in each
271
- probe before their use, as the value is otherwise considered
272
- undefined.
276
+ DTrace implements three different scopes of variables: global, thread-local and
277
+ clause-local. Global variables are visible to every probe and across all
278
+ threads, allowing the user to write scripts that carry state across multiple
279
+ threads should it be necessary and are identified with the variable name.
280
+
281
+ Similar to global variables are D built-in variables such as \verb |execname |,
282
+ \verb |curthread |, etc. We make a distinction between the two due to the
283
+ difference between failures that they expose. A list of built-in variables can
284
+ be found in Section~\ref {sec:builtin-variables-ref }.
285
+
286
+ Thread-local variables are only visible within a single software thread, they
287
+ are represented in source code as prefixed with \texttt {self-> }. A thread-local
288
+ variable is identified with its name and a thread ID.
289
+
290
+ % XXX: Clause-local variables are ill-defined in DTrace and we need to figure
291
+ % out a way to talk about them in a more precise manner.
292
+ Clause-local variables are prefixed with \texttt {this-> } and are visible only
293
+ within a single \texttt {dtrace\_ probe() } call. This means that a clause-local
294
+ variable will be visible across multiple clauses of the same probe, allowing the
295
+ programmer to carry state associated with a clause-local variable across them.
273
296
274
297
\subsection {Global variables }
275
298
\label {subsec:global-variables }
276
299
277
- Any variable introduced in a D script that is not declared as part of
278
- a \verb |this-> | or \verb |self-> | is considered to be global in scope,
279
- meaning that it can be accessed from any action associated with a
280
- probe when a set of probes are simultaneously activated. Global
281
- variables are allocated and instantiated when they are first
282
- referenced.
300
+ Any variable introduced in a D script that is not declared as part of a
301
+ \verb |this-> | or \verb |self-> | is considered to be global in scope, meaning that
302
+ it can be accessed from any action associated with a probe when a set of probes
303
+ are simultaneously activated. Global variables are allocated and instantiated
304
+ when they are first assigned to. Global variables, however, are subject to the
305
+ semantics of the underlying architecture's cache coherence mechanism.
306
+
307
+ Global variables exhibit two failure modes:
308
+ \begin {itemize }
309
+ \item The variable could not be allocated.
310
+ \item The use of a global variable has caused a fault.
311
+ \end {itemize }
312
+ The former eventually manifests through the latter failure mode at every program
313
+ point where the variable is used, but we have included it as a separate failure
314
+ mode because DTrace currently increments an according counter to indicate that a
315
+ variable could not be allocated and because it has different implications on the
316
+ rest of the D script.
317
+
318
+ \subsection {Built-in variables }
319
+ \label {subsec:builtin-variables }
320
+
321
+ Similarly to global variables, built-in variables are accessible to the
322
+ programmer at any point in the script. The main difference between built-in
323
+ variables and global variables are their semantics. D built-in variables are not
324
+ mutable and are thus not subject to the concurrency semantics of the underlying
325
+ architecture. Furthermore, unlike global variables, built-in variables are
326
+ guaranteed to never cause a page fault and thus can be accessed safely. It is up
327
+ to the DTrace implementation has to ensure that access to these variables is
328
+ race-free and reliable.
283
329
284
330
\subsection {Thread-local variables }
285
331
\label {subsec:thread-local-variables }
286
332
333
+ As previously mentioned, thread-local variables are identified with their name
334
+ and a thread ID. The motivation behind them is to have a pragmatic way to carry
335
+ state around probes in a race-free way, as a thread can only be scheduled on a
336
+ single CPU. The failure modes exposed by thread-local variables are the those of
337
+ global variables -- however, thread-local variables do not suffer the problem of
338
+ relying on the underlying architecture's cache coherence semantics under the
339
+ assumption that each software thread can only be scheduled on one CPU and runs
340
+ with interrupts off in the DTrace probe context.
341
+
287
342
\subsection {Clause-local variables }
288
343
\label {subsec:clause-local-variables }
289
344
0 commit comments