Commit 660b8a8
authored
feat(otel_thread_ctx): thread-level ctx publication (#1791)
# What does this PR do?
This PR implements a first version of publishing side of the [OTel proposal on thread-level context sharing](https://github.com/open-telemetry/opentelemetry-specification/pull/4947/changes).
The changes are two-folds:
1. Add a C shim for accessing the correct thread-local variable that holds the thread context. Indeed the spec mandates the use of the TLSDESC dialect, but this isn't possible in Rust, which uses the classical TLS dialect (`gnu` instead of `gnu2`) by default. This is not possible to configure on stable Rust. See additional notes below for more details.
2. Add a new `otel_thread_ctx` module, similar to the `otel_process_ctx` one, which provides an abstraction over the thread-level context and handle attach/detach/modify.
The part of the spec around the interned string table, hooking it up in the process-level ctx and tracer metadata is left for future work.
# Motivation
See the corresponding OTEP linked above for more details on the motivation.
# Additional Notes
TLSDESC is chosen in the spec for performance reasons. I initially found a bit sad that we have to call to a C function from `libdatadog` to retrieve the TLS address, which incurs an additional cost. I researched potential alternatives:
- force Rust to use the TLSDESC dialect. This is just not possible/supported.
- cache the address (which is stable per thread). But this must be put in...drumroll... another thread-local variable, since it's well, thread-local, so back to square one. One possibility would be to use a `cached_addr` thread-local and force the access to use the `initial-exec` model, which is very fast (the price to pay is that libdatadog coulnd't be `dlopen` at runtime, but I'm not sure there's any usage for that). We would trade a function call for an offset and loads, which I expect to be faster. But this requires [nightly Rust](https://doc.rust-lang.org/unstable-book/compiler-flags/tls-model.html), unfortunately, and would apply to the entirety of `libdatadog`.
- inline-asm: the access sequence for TLSDESC is really simple (it's a few LLVM IR instructions, calling a function obtained from the global offset table). I looked into inline LLVM assembly for Rust, but it's not supported and is anon-goal (LLVM is almost considered as an implementation detail, as rust-gcc could one day become a viable alternative, for example). Native ASM is just too much hassle to pay off.
All in all, I think there's no simple, reasonable, portable and maintainable alternative to the C shim for now. It is worth noting that calling to the C shim is likely to be still faster than the default TLS model chosen by Rust in a dynamic library (the latter requires a function call to `__get_tls_addr` anyway, but that function is more involved). I wonder if some aggressive cross-language late LTO could inline the C shim.
# How to test the change?
There are a bunch of tests in this PR. Ideally we will later test this against other thread-level ctx readers implementations once we hook this work in the FFI; this is left for a follow-up.
Co-authored-by: yann.hamdaoui <yann.hamdaoui@datadoghq.com>1 parent 15860bb commit 660b8a8
7 files changed
Lines changed: 671 additions & 2 deletions
File tree
- libdd-library-config/src
- libdd-profiling
- src
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
| 84 | + | |
84 | 85 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
14 | 30 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
17 | 18 | | |
18 | 19 | | |
0 commit comments