Closed nbaksalyar closed 1 year ago
define the semaphore in Rust using [static var]
I can confirm that this approach works perfectly in the following example:
#[no_mangle]
#[link_section = ".probes"]
pub static SEMAPHORE: u16 = 0;
println!("semaphore {}", if ::std::ptr::read_volatile(&SEMAPHORE) == 1 {
"enabled"
} else {
"disabled"
});
::core::arch::asm!(concat!(r#"
990: nop
.pushsection .note.stapsdt,"?","note"
...
993: ."#, $size, r#"byte 990b
."#, $size, r#"byte _.stapsdt.base
."#, $size, r#"byte SEMAPHORE
... "#
)
However, the probe definition needs to be decoupled from the actual probe instruction (990: nop
) for this to work properly with arguments evaluation.
This was released in 0.4.0, and then moved to probe_lazy!
in 0.5.0, also with link_section
added.
The original example can now look like:
probe_lazy!(foo, bar, heavy_compute_fn());
You could also write more complicated block expressions there, even filling multiple args:
{
let len;
probe_lazy!(foo, bar, {
let vec = heavy_compute_fn();
len = vec.len();
vec.as_ptr()
}, len);
}
That's not be as convenient as a separate probe_enabled!()
would be, but I don't have any idea how to make that actually work, unless we use some explicit mangling that's not very "rustic".
Currently, the SystemTap semaphore functionality is not used. It's very useful for probes that require expensive computation.
As suggested in the fixme comment, we can introduce a new macro,
probe_enabled!(provider, name) -> bool
, which will automatically generate code for a conditional probe. Example use case:It'd be also good to support a shorthand conditional probe macro, e.g.:
probe_if_enabled!(provider, name, arg1, arg2)
in which case args will be computed only if the corresponding probe is enabled, e.g.:This feature should be fairly straightforward to implement. For each semaphore, we'll need to check if there is a corresponding symbol in the
.probes
section. If it does not exist, we'll need to create it. Then, in the.note.stapsdt
section, when we define a probe, we'll just need to refer to this symbol's address when we define a semaphore for a probe. Forprobe_enabled
, it should suffice to read the memory at the corresponding.probes
symbol offset.Or, alternatively, even a simpler approach: define the semaphore var in Rust using
#[link_section(".probes")] static FOO_SEMAPHORE = ...;
.