Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/tracy-client/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/tracy-client/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"Cargo.toml":"8f0517ddbb0c8bd2f3f641fb07c06f31317dbee536f11dbb5ed86421fc4d9370","FEATURES.mkd":"69d3909888fa40cb568254983f8901d1f13e1b0af0a8af5b44ae899612e9c8fe","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.mkd":"d06643cfb277a6b84c32a614ba36429c11f61b5b0ddcf756e931ed80352c59e8","benches/client.rs":"993b8818c1c8d2ac0d8e14ed4f66faa855f24ec75dbf006ad82cadba8929d465","src/frame.rs":"4bcdf7a95793bffaf50aa8ec2e497163516c15164fdcfb725510fd910ad064be","src/lib.rs":"487e3268ba40aa456cebc4a9ade3879e852960507e47a539cd5ee1f781440d98","src/plot.rs":"9fe5d4215c8d10d3cd8306e44fa15b36e413e383fac5b55909e5bd4254041730","src/span.rs":"0f86a078bcbc172af9243fb886506c8e836233945f33a0028ba9c185b15512da","src/state.rs":"178843ae073c17b18d14d62f6cacf778a431e9d3341c7aef9a7a65d95d392d13","tests/loom.rs":"8d89230354c88ef046ae9ac338b7c94320cd4fac64a32603c82b47910b3ad39d","tests/tests.rs":"28a01f919930c6159e8ee0d54bf727077e1374a5f6dbccf6b0f65a11e3551472"},"package":"434ecabbda9f67eeea1eab44d52f4a20538afa3e2c2770f2efc161142b25b608"}
|
||||
84
third-party/vendor/tracy-client/Cargo.toml
vendored
Normal file
84
third-party/vendor/tracy-client/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "tracy-client"
|
||||
version = "0.15.2"
|
||||
authors = ["Simonas Kazlauskas <tracy-client@kazlauskas.me>"]
|
||||
description = """
|
||||
High level bindings to the client libraries for the Tracy profiler
|
||||
"""
|
||||
homepage = "https://github.com/nagisa/rust_tracy_client"
|
||||
documentation = "https://docs.rs/tracy-client"
|
||||
readme = "README.mkd"
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/nagisa/rust_tracy_client"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
rustdoc-args = [
|
||||
"--cfg",
|
||||
"tracy_client_docs",
|
||||
]
|
||||
|
||||
[[test]]
|
||||
name = "tests"
|
||||
path = "tests/tests.rs"
|
||||
harness = false
|
||||
|
||||
[[test]]
|
||||
name = "loom"
|
||||
path = "tests/loom.rs"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "client"
|
||||
path = "benches/client.rs"
|
||||
harness = false
|
||||
|
||||
[dependencies.once_cell]
|
||||
version = "1.10"
|
||||
|
||||
[dependencies.sys]
|
||||
version = ">=0.17.0, <0.22.0"
|
||||
features = [
|
||||
"manual-lifetime",
|
||||
"delayed-init",
|
||||
]
|
||||
default-features = false
|
||||
package = "tracy-client-sys"
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3"
|
||||
|
||||
[features]
|
||||
broadcast = ["sys/broadcast"]
|
||||
code-transfer = ["sys/code-transfer"]
|
||||
context-switch-tracing = ["sys/context-switch-tracing"]
|
||||
default = [
|
||||
"enable",
|
||||
"system-tracing",
|
||||
"context-switch-tracing",
|
||||
"sampling",
|
||||
"code-transfer",
|
||||
"broadcast",
|
||||
]
|
||||
enable = ["sys/enable"]
|
||||
fibers = ["sys/fibers"]
|
||||
ondemand = ["sys/ondemand"]
|
||||
only-ipv4 = ["sys/only-ipv4"]
|
||||
only-localhost = ["sys/only-localhost"]
|
||||
sampling = ["sys/sampling"]
|
||||
system-tracing = ["sys/system-tracing"]
|
||||
timer-fallback = ["sys/timer-fallback"]
|
||||
|
||||
[target."cfg(loom)".dependencies.loom]
|
||||
version = "0.5"
|
||||
24
third-party/vendor/tracy-client/FEATURES.mkd
vendored
Normal file
24
third-party/vendor/tracy-client/FEATURES.mkd
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
* `enable` – enables the Tracy client. Corresponds to the `TRACY_ENABLE` define.
|
||||
* `system-tracing` – enable capture of system level details. Corresponds to the
|
||||
`TRACY_NO_SYSTEM_TRACING` define.
|
||||
* `context-switch-tracing` – enable capture of the context switch data. Corresponds to the
|
||||
`TRACY_NO_CONTEXT_SWITCH` define.
|
||||
* `sampling` – enable periodic sampling of the call stack. Corresponds to the
|
||||
`TRACY_NO_SAMPLING` define.
|
||||
* `code-transfer` – enable transfer of the machine code to the profiler. Corresponds to the
|
||||
`TRACY_NO_CODE_TRANSFER` define.
|
||||
* `broadcast` – announce presence of the client to the profilers on the local network.
|
||||
Corresponds to the `TRACY_NO_BROADCAST` define.
|
||||
* `only-localhost` – listen for profilers on the localhost interface only. Corresponds to the
|
||||
`TRACY_ONLY_LOCALHOST` define.
|
||||
* `only-ipv4` – listen for profilers on IPv4 interfaces only. Corresponds to the
|
||||
`TRACY_ONLY_IPV4` define.
|
||||
* `timer-fallback` – allow running on devices without a high resolution timer support.
|
||||
Corresponds to the `TRACY_TIMER_FALLBACK` define.
|
||||
* `ondemand` – start collecting traces only when a server connects to the client. Corresponds
|
||||
to the `TRACY_ON_DEMAND` define.
|
||||
* `fibers` – enable support for instrumenting fibers, coroutines and similar such asynchrony
|
||||
primitives. Corresponds to the `TRACY_FIBERS` define.
|
||||
|
||||
Refer to this package's `Cargo.toml` for the list of the features enabled by default. Refer to
|
||||
the `Tracy` manual for more information on the implications of each feature.
|
||||
176
third-party/vendor/tracy-client/LICENSE-APACHE
vendored
Normal file
176
third-party/vendor/tracy-client/LICENSE-APACHE
vendored
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
23
third-party/vendor/tracy-client/LICENSE-MIT
vendored
Normal file
23
third-party/vendor/tracy-client/LICENSE-MIT
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
54
third-party/vendor/tracy-client/README.mkd
vendored
Normal file
54
third-party/vendor/tracy-client/README.mkd
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# Tracy profiler clients in Rust
|
||||
|
||||
This project contains Rust crates for producing [Tracy profiler](https://github.com/wolfpld/tracy)
|
||||
traces. Tracy features nanosecond precision, ability to profile remotely and a full-featured
|
||||
graphical interface for finding hot spots in profiled programs.
|
||||
|
||||
While Tracy's support for Rust is not first-class, it is still a very potent tool. If you have an
|
||||
application instrumented with the `tracing` crate, Tracy can be used with your program in minutes
|
||||
via the `tracing-tracy` crate. It can work well as both a profiling and, to a lesser extent,
|
||||
an observability tool.
|
||||
|
||||
## Important note
|
||||
|
||||
Depending on the configuration Tracy may broadcast discovery packets to the local network and
|
||||
expose the data it collects in the background to that same network. Traces collected by Tracy
|
||||
may include source and assembly code as well.
|
||||
|
||||
As thus, you may want make sure to only enable the `tracing-tracy`, `tracy-client` and
|
||||
`tracy-client-sys` crates conditionally, via the `enable` feature flag provided by the crates.
|
||||
|
||||
## Version support table
|
||||
|
||||
This project, unlike Tracy itself, follows semantic versioning. We will publish a breaking version
|
||||
bump for `tracy-client-sys` whenever there is a potentially breaking protocol change, even if the
|
||||
`Tracy` project itself does not. An older version of `Tracy` being unable to communicate with the
|
||||
client of a more recent version is an example of such a breaking change.
|
||||
|
||||
`tracy-client`, `tracing-tracy` and other crates also follow semantic versioning, but do not
|
||||
consider protocol breaks a breaking change for their purposes. For that reason each future version
|
||||
of `tracy-client` may be able to support depending on a large number of incompatible
|
||||
`tracy-client-sys` versions. Users are expected to select the version of `Tracy` profiler they
|
||||
target and use precise version bounds in `Cargo.toml` or `Cargo.lock` to specify the version of
|
||||
`tracy-client-sys` that they want to use.
|
||||
|
||||
The following table lists the version correspondence between the libraries.
|
||||
|
||||
| Tracy | tracy-client-sys | tracy-client | tracing-tracy |
|
||||
| ----- | ---------------- | ------------ | ------------- |
|
||||
| 0.7.1 | 0.9.0 | 0.8.0 | 0.2.0 |
|
||||
| 0.7.3 | 0.10.0 | 0.9.0 | 0.3.0 |
|
||||
| 0.7.4 | 0.11.0 | 0.10.0 | 0.4.0 |
|
||||
| 0.7.5 | 0.12.0 | 0.11.0 | 0.5.0 |
|
||||
| 0.7.6 | 0.13.0, 0.14.0 | 0.12.* | 0.6.* |
|
||||
| v0.7.7 | 0.15.0 | 0.12.* | 0.6.* |
|
||||
| v0.7.8 | 0.16.0 | 0.12.* | 0.6.* |
|
||||
| v0.7.8 | 0.16.0 | 0.12.* | 0.7.* |
|
||||
| v0.7.8 | 0.16.0 | 0.12.* | 0.8.* |
|
||||
| v0.8.1 | 0.17.* | 0.13.* | 0.9.* |
|
||||
| v0.8.1 | 0.17.* | 0.14.* | 0.10.* |
|
||||
| v0.8.2 | 0.18.0 | 0.14.* | 0.10.* |
|
||||
| v0.9 | 0.19.0 | 0.14.2 | 0.10.0 |
|
||||
| v0.9 | 0.19.0 | 0.15.0 | 0.10.1 |
|
||||
| v0.9.1 | 0.21.0 | 0.14.2 | 0.10.2 |
|
||||
<!-- AUTO-UPDATE -->
|
||||
60
third-party/vendor/tracy-client/benches/client.rs
vendored
Normal file
60
third-party/vendor/tracy-client/benches/client.rs
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use tracy_client::Client;
|
||||
|
||||
fn client_start(c: &mut Criterion) {
|
||||
let mut clients = Vec::<Client>::with_capacity(1_000_000_000);
|
||||
c.bench_function("start", |b| b.iter(|| clients.push(Client::start())));
|
||||
}
|
||||
|
||||
fn client_clone(c: &mut Criterion) {
|
||||
let mut clients = Vec::<Client>::with_capacity(1_000_000_000);
|
||||
let client = Client::start();
|
||||
c.bench_function("clone", |b| b.iter(|| clients.push(client.clone())));
|
||||
}
|
||||
|
||||
fn client_running(c: &mut Criterion) {
|
||||
let _client = Client::start();
|
||||
c.bench_function("running", |b| b.iter(|| Client::running()));
|
||||
}
|
||||
|
||||
fn ops_alloc(c: &mut Criterion) {
|
||||
let client = tracy_client::Client::start();
|
||||
c.bench_function("span_alloc_callstack/0", |bencher| {
|
||||
bencher.iter(|| {
|
||||
client
|
||||
.clone()
|
||||
.span_alloc("hello", "function", "file", 42, 0);
|
||||
});
|
||||
});
|
||||
c.bench_function("span_alloc_callstack/100", |bencher| {
|
||||
bencher.iter(|| {
|
||||
client
|
||||
.clone()
|
||||
.span_alloc("hello", "function", "file", 42, 100);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn ops_static(c: &mut Criterion) {
|
||||
let _client = tracy_client::Client::start();
|
||||
c.bench_function("span_callstack/0", |bencher| {
|
||||
bencher.iter(|| {
|
||||
tracy_client::span!("some_name", 0);
|
||||
});
|
||||
});
|
||||
c.bench_function("span_callstack/100", |bencher| {
|
||||
bencher.iter(|| {
|
||||
tracy_client::span!("some_name", 100);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
client_start,
|
||||
client_clone,
|
||||
client_running,
|
||||
ops_alloc,
|
||||
ops_static
|
||||
);
|
||||
criterion_main!(benches);
|
||||
149
third-party/vendor/tracy-client/src/frame.rs
vendored
Normal file
149
third-party/vendor/tracy-client/src/frame.rs
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
use crate::Client;
|
||||
|
||||
/// A non-continuous frame region.
|
||||
///
|
||||
/// Create with the [`Client::non_continuous_frame`] function.
|
||||
pub struct Frame(Client, FrameName);
|
||||
|
||||
/// A name for secondary and non-continuous frames.
|
||||
///
|
||||
/// Create with the [`frame_name!`] macro.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct FrameName(pub(crate) &'static str);
|
||||
|
||||
/// Instrumentation for global frame indicators.
|
||||
impl Client {
|
||||
/// Indicate that rendering of a continuous frame has ended.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// In a traditional rendering scenarios a frame mark should be inserted after a buffer swap.
|
||||
///
|
||||
/// ```
|
||||
/// use tracy_client::Client;
|
||||
/// # fn swap_buffers() {}
|
||||
/// # let client = tracy_client::Client::start();
|
||||
/// // loop {
|
||||
/// // ...
|
||||
/// swap_buffers();
|
||||
/// Client::running().expect("client must be running").frame_mark();
|
||||
/// // }
|
||||
/// ```
|
||||
pub fn frame_mark(&self) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
sys::___tracy_emit_frame_mark(std::ptr::null());
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicate that rendering of a secondary (named) continuous frame has ended.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Much like with the primary frame mark, the secondary (named) frame mark should be inserted
|
||||
/// after some continuously repeating operation finishes one iteration of its processing.
|
||||
///
|
||||
/// ```
|
||||
/// use tracy_client::frame_name;
|
||||
/// # fn physics_tick() {}
|
||||
/// # let client = tracy_client::Client::start();
|
||||
/// // loop {
|
||||
/// // ...
|
||||
/// physics_tick();
|
||||
/// tracy_client::Client::running()
|
||||
/// .expect("client must be running")
|
||||
/// .secondary_frame_mark(frame_name!("physics"));
|
||||
/// // }
|
||||
/// ```
|
||||
pub fn secondary_frame_mark(&self, name: FrameName) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
// SAFE: We ensured that the name would be null-terminated.
|
||||
sys::___tracy_emit_frame_mark(name.0.as_ptr().cast());
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicate that a processing of a non-continuous frame has begun.
|
||||
///
|
||||
/// Dropping the returned [`Frame`] will terminate the non-continuous frame.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use tracy_client::frame_name;
|
||||
/// # let client = tracy_client::Client::start();
|
||||
/// tracy_client::Client::running()
|
||||
/// .expect("client must be running")
|
||||
/// .non_continuous_frame(frame_name!("a frame"));
|
||||
/// ```
|
||||
pub fn non_continuous_frame(&self, name: FrameName) -> Frame {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
// SAFE: We ensure that the name would be null-terminated.
|
||||
sys::___tracy_emit_frame_mark_start(name.0.as_ptr().cast());
|
||||
}
|
||||
Frame(self.clone(), name)
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a [`FrameName`].
|
||||
///
|
||||
/// The resulting value may be used as an argument for the the [`Client::secondary_frame_mark`] and
|
||||
/// [`Client::non_continuous_frame`] methods. The macro can be used in a `const` context.
|
||||
#[macro_export]
|
||||
macro_rules! frame_name {
|
||||
($name: literal) => {{
|
||||
unsafe { $crate::internal::create_frame_name(concat!($name, "\0")) }
|
||||
}};
|
||||
}
|
||||
|
||||
impl Drop for Frame {
|
||||
fn drop(&mut self) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
// SAFE: We ensure that thena me would be null-terminated. We also still have an owned
|
||||
// Client handle.
|
||||
sys::___tracy_emit_frame_mark_end(self.1 .0.as_ptr().cast());
|
||||
std::convert::identity(&self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience shortcut for [`Client::frame_mark`] on the current client.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// - If a `Client` isn't currently running.
|
||||
pub fn frame_mark() {
|
||||
Client::running()
|
||||
.expect("frame_mark! without a running Client")
|
||||
.frame_mark();
|
||||
}
|
||||
|
||||
/// Convenience macro for [`Client::secondary_frame_mark`] on the current client.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// - If a `Client` isn't currently running.
|
||||
#[macro_export]
|
||||
macro_rules! secondary_frame_mark {
|
||||
($name: literal) => {{
|
||||
$crate::Client::running()
|
||||
.expect("secondary_frame_mark! without a running Client")
|
||||
.secondary_frame_mark($crate::frame_name!($name))
|
||||
}};
|
||||
}
|
||||
|
||||
/// Convenience macro for [`Client::non_continuous_frame`] on the current client.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// - If a `Client` isn't currently running.
|
||||
#[macro_export]
|
||||
macro_rules! non_continuous_frame {
|
||||
($name: literal) => {{
|
||||
$crate::Client::running()
|
||||
.expect("non_continuous_frame! without a running Client")
|
||||
.non_continuous_frame($crate::frame_name!($name))
|
||||
}};
|
||||
}
|
||||
281
third-party/vendor/tracy-client/src/lib.rs
vendored
Normal file
281
third-party/vendor/tracy-client/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
#![deny(unsafe_op_in_unsafe_fn, missing_docs)]
|
||||
#![cfg_attr(not(feature = "enable"), allow(unused_variables, unused_imports))]
|
||||
//! This crate is a set of safe bindings to the client library of the [Tracy profiler].
|
||||
//!
|
||||
//! If you have already instrumented your application with `tracing`, consider the `tracing-tracy`
|
||||
//! crate.
|
||||
//!
|
||||
//! [Tracy profiler]: https://github.com/wolfpld/tracy
|
||||
//!
|
||||
//! # Important note
|
||||
//!
|
||||
//! Depending on the configuration Tracy may broadcast discovery packets to the local network and
|
||||
//! expose the data it collects in the background to that same network. Traces collected by Tracy
|
||||
//! may include source and assembly code as well.
|
||||
//!
|
||||
//! As thus, you may want make sure to only enable the `tracy-client` crate conditionally, via
|
||||
//! the `enable` feature flag provided by this crate.
|
||||
//!
|
||||
//! # Features
|
||||
//!
|
||||
//! The following crate features are provided to customize the functionality of the Tracy client:
|
||||
//!
|
||||
#![doc = include_str!("../FEATURES.mkd")]
|
||||
#![cfg_attr(tracy_client_docs, feature(doc_auto_cfg))]
|
||||
|
||||
pub use crate::frame::{frame_mark, Frame, FrameName};
|
||||
pub use crate::plot::PlotName;
|
||||
pub use crate::span::{Span, SpanLocation};
|
||||
use std::alloc;
|
||||
use std::ffi::CString;
|
||||
pub use sys;
|
||||
|
||||
mod frame;
|
||||
mod plot;
|
||||
mod span;
|
||||
mod state;
|
||||
|
||||
/// /!\ /!\ Please don't rely on anything in this module T_T /!\ /!\
|
||||
#[doc(hidden)]
|
||||
pub mod internal {
|
||||
pub use crate::{span::SpanLocation, sys};
|
||||
pub use once_cell::sync::Lazy;
|
||||
pub use std::any::type_name;
|
||||
pub use std::ptr::null;
|
||||
use std::ffi::CString;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn make_span_location(
|
||||
type_name: &'static str,
|
||||
span_name: *const u8,
|
||||
file: *const u8,
|
||||
line: u32,
|
||||
) -> crate::SpanLocation {
|
||||
#[cfg(feature = "enable")]
|
||||
{
|
||||
let function_name = CString::new(&type_name[..type_name.len() - 3]).unwrap();
|
||||
crate::SpanLocation {
|
||||
data: crate::sys::___tracy_source_location_data {
|
||||
name: span_name.cast(),
|
||||
function: function_name.as_ptr(),
|
||||
file: file.cast(),
|
||||
line,
|
||||
color: 0,
|
||||
},
|
||||
_function_name: function_name,
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "enable"))]
|
||||
crate::SpanLocation { _internal: () }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub const unsafe fn create_frame_name(name: &'static str) -> crate::frame::FrameName {
|
||||
crate::frame::FrameName(name)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub const unsafe fn create_plot(name: &'static str) -> crate::plot::PlotName {
|
||||
crate::plot::PlotName(name)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
/// Safety: `name` must be null-terminated, and a `Client` must be enabled
|
||||
pub unsafe fn set_thread_name(name: *const u8) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
sys::___tracy_set_thread_name(name.cast())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A type representing an enabled Tracy client.
|
||||
///
|
||||
/// Obtaining a `Client` is required in order to instrument the application.
|
||||
///
|
||||
/// Multiple copies of a Client may be live at once. As long as at least one `Client` value lives,
|
||||
/// the `Tracy` client is enabled globally. In addition to collecting information through the
|
||||
/// instrumentation inserted by you, the Tracy client may automatically collect information about
|
||||
/// execution of the program while it is enabled. All this information may be stored in memory
|
||||
/// until a profiler application connects to the client to read the data.
|
||||
///
|
||||
/// Depending on the build configuration, the client may collect and make available machine
|
||||
/// and source code of the application as well as other potentially sensitive information.
|
||||
///
|
||||
/// When all of the `Client` values are dropped, the underlying Tracy client will be shut down as
|
||||
/// well. Shutting down the `Client` will discard any information gathered up to that point that
|
||||
/// still hasn't been delivered to the profiler application.
|
||||
pub struct Client(());
|
||||
|
||||
/// Instrumentation methods for outputting events occurring at a specific instant.
|
||||
///
|
||||
/// Data provided by this instrumentation can largely be considered to be equivalent to logs.
|
||||
impl Client {
|
||||
/// Output a message.
|
||||
///
|
||||
/// Specifying a non-zero `callstack_depth` will enable collection of callstack for this
|
||||
/// message. The number provided will limit the number of call frames collected. Note that
|
||||
/// enabling callstack collection introduces a non-trivial amount of overhead to this call.
|
||||
pub fn message(&self, message: &str, callstack_depth: u16) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
let stack_depth = adjust_stack_depth(callstack_depth).into();
|
||||
sys::___tracy_emit_message(message.as_ptr().cast(), message.len(), stack_depth)
|
||||
}
|
||||
}
|
||||
|
||||
/// Output a message with an associated color.
|
||||
///
|
||||
/// Specifying a non-zero `callstack_depth` will enable collection of callstack for this
|
||||
/// message. The number provided will limit the number of call frames collected. Note that
|
||||
/// enabling callstack collection introduces a non-trivial amount of overhead to this call.
|
||||
///
|
||||
/// The colour shall be provided as RGBA, where the least significant 8 bits represent the alpha
|
||||
/// component and most significant 8 bits represent the red component.
|
||||
pub fn color_message(&self, message: &str, rgba: u32, callstack_depth: u16) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
let depth = adjust_stack_depth(callstack_depth).into();
|
||||
sys::___tracy_emit_messageC(message.as_ptr().cast(), message.len(), rgba >> 8, depth)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// Set the current thread name to the provided value.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if the name contains interior null characters.
|
||||
pub fn set_thread_name(&self, name: &str) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
let name = CString::new(name).unwrap();
|
||||
// SAFE: `name` is a valid null-terminated string.
|
||||
internal::set_thread_name(name.as_ptr().cast());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience macro for [`Client::set_thread_name`] on the current client.
|
||||
///
|
||||
/// Note that any interior null characters terminate the name early. This is not checked for.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// - If a `Client` isn't currently running.
|
||||
#[macro_export]
|
||||
macro_rules! set_thread_name {
|
||||
($name: literal) => {{
|
||||
$crate::Client::running().expect("set_thread_name! without a running Client");
|
||||
unsafe {
|
||||
// SAFE: `name` is a valid null-terminated string.
|
||||
$crate::internal::set_thread_name(concat!($name, "\0").as_ptr().cast())
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// A profiling wrapper around another allocator.
|
||||
///
|
||||
/// See documentation for [`std::alloc`](std::alloc) for more information about global allocators.
|
||||
///
|
||||
/// Note that this wrapper will start up the client on the first allocation, if not enabled
|
||||
/// already.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// In your executable, add:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use tracy_client::*;
|
||||
/// #[global_allocator]
|
||||
/// static GLOBAL: ProfiledAllocator<std::alloc::System> =
|
||||
/// ProfiledAllocator::new(std::alloc::System, 100);
|
||||
/// ```
|
||||
pub struct ProfiledAllocator<T>(T, u16);
|
||||
|
||||
impl<T> ProfiledAllocator<T> {
|
||||
/// Construct a new `ProfiledAllocator`.
|
||||
///
|
||||
/// Specifying a non-zero `callstack_depth` will enable collection of callstack for this
|
||||
/// message. The number provided will limit the number of call frames collected. Note that
|
||||
/// enabling callstack collection introduces a non-trivial amount of overhead to each
|
||||
/// allocation and deallocation.
|
||||
pub const fn new(inner_allocator: T, callstack_depth: u16) -> Self {
|
||||
Self(inner_allocator, adjust_stack_depth(callstack_depth))
|
||||
}
|
||||
|
||||
fn emit_alloc(&self, ptr: *mut u8, size: usize) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
Client::start();
|
||||
if self.1 == 0 {
|
||||
sys::___tracy_emit_memory_alloc(ptr.cast(), size, 1);
|
||||
} else {
|
||||
sys::___tracy_emit_memory_alloc_callstack(ptr.cast(), size, self.1.into(), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_free(&self, ptr: *mut u8) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
if self.1 == 0 {
|
||||
sys::___tracy_emit_memory_free(ptr.cast(), 1);
|
||||
} else {
|
||||
sys::___tracy_emit_memory_free_callstack(ptr.cast(), self.1.into(), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: alloc::GlobalAlloc> alloc::GlobalAlloc for ProfiledAllocator<T> {
|
||||
unsafe fn alloc(&self, layout: alloc::Layout) -> *mut u8 {
|
||||
let alloc = unsafe {
|
||||
// SAFE: all invariants satisfied by the caller.
|
||||
self.0.alloc(layout)
|
||||
};
|
||||
self.emit_alloc(alloc, layout.size());
|
||||
alloc
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: alloc::Layout) {
|
||||
self.emit_free(ptr);
|
||||
unsafe {
|
||||
// SAFE: all invariants satisfied by the caller.
|
||||
self.0.dealloc(ptr, layout)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn alloc_zeroed(&self, layout: alloc::Layout) -> *mut u8 {
|
||||
let alloc = unsafe {
|
||||
// SAFE: all invariants satisfied by the caller.
|
||||
self.0.alloc_zeroed(layout)
|
||||
};
|
||||
self.emit_alloc(alloc, layout.size());
|
||||
alloc
|
||||
}
|
||||
|
||||
unsafe fn realloc(&self, ptr: *mut u8, layout: alloc::Layout, new_size: usize) -> *mut u8 {
|
||||
self.emit_free(ptr);
|
||||
let alloc = unsafe {
|
||||
// SAFE: all invariants satisfied by the caller.
|
||||
self.0.realloc(ptr, layout, new_size)
|
||||
};
|
||||
self.emit_alloc(alloc, new_size);
|
||||
alloc
|
||||
}
|
||||
}
|
||||
|
||||
/// Clamp the stack depth to the maximum supported by Tracy.
|
||||
#[inline(always)]
|
||||
pub(crate) const fn adjust_stack_depth(depth: u16) -> u16 {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
62 ^ ((depth ^ 62) & 0u16.wrapping_sub((depth < 62) as _))
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
depth
|
||||
}
|
||||
}
|
||||
53
third-party/vendor/tracy-client/src/plot.rs
vendored
Normal file
53
third-party/vendor/tracy-client/src/plot.rs
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
use crate::Client;
|
||||
|
||||
/// Name of a plot.
|
||||
///
|
||||
/// Create with the [`plot_name!`](crate::plot_name) macro.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct PlotName(pub(crate) &'static str);
|
||||
|
||||
/// Instrumentation for drawing 2D plots.
|
||||
impl Client {
|
||||
/// Add a point with an y-axis value of `value` to the plot named `plot_name`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # let client = tracy_client::Client::start();
|
||||
/// tracy_client::Client::running()
|
||||
/// .expect("client must be running")
|
||||
/// .plot(tracy_client::plot_name!("temperature"), 37.0);
|
||||
/// ```
|
||||
pub fn plot(&self, plot_name: PlotName, value: f64) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
// SAFE: We made sure the `plot` refers to a null-terminated string.
|
||||
sys::___tracy_emit_plot(plot_name.0.as_ptr().cast(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a [`PlotName`].
|
||||
///
|
||||
/// The resulting value may be used as an argument for the [`Client::plot`] method. The macro can
|
||||
/// be used in a `const` context.
|
||||
#[macro_export]
|
||||
macro_rules! plot_name {
|
||||
($name: expr) => {
|
||||
unsafe { $crate::internal::create_plot(concat!($name, "\0")) }
|
||||
};
|
||||
}
|
||||
|
||||
/// Convenience macro for [`Client::plot`] on the current client.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// - If a `Client` isn't currently running.
|
||||
#[macro_export]
|
||||
macro_rules! plot {
|
||||
($name: expr, $value: expr) => {{
|
||||
$crate::Client::running()
|
||||
.expect("plot! without a running Client")
|
||||
.plot($crate::plot_name!($name), $value)
|
||||
}};
|
||||
}
|
||||
275
third-party/vendor/tracy-client/src/span.rs
vendored
Normal file
275
third-party/vendor/tracy-client/src/span.rs
vendored
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
use crate::{adjust_stack_depth, Client};
|
||||
use std::ffi::CString;
|
||||
|
||||
/// A handle representing a span of execution.
|
||||
///
|
||||
/// The trace span will be ended when this type is dropped.
|
||||
pub struct Span {
|
||||
#[cfg(feature = "enable")]
|
||||
client: Client,
|
||||
#[cfg(feature = "enable")]
|
||||
zone: sys::___tracy_c_zone_context,
|
||||
#[cfg(feature = "enable")]
|
||||
_no_send_sync: std::marker::PhantomData<*mut sys::___tracy_c_zone_context>,
|
||||
#[cfg(not(feature = "enable"))]
|
||||
_no_send_sync: std::marker::PhantomData<*mut ()>,
|
||||
}
|
||||
|
||||
/// A statically allocated location information for a span.
|
||||
///
|
||||
/// Construct with the [`span_location!`](crate::span_location) macro.
|
||||
pub struct SpanLocation {
|
||||
#[cfg(feature = "enable")]
|
||||
pub(crate) _function_name: CString,
|
||||
#[cfg(feature = "enable")]
|
||||
pub(crate) data: sys::___tracy_source_location_data,
|
||||
#[cfg(not(feature = "enable"))]
|
||||
pub(crate) _internal: (),
|
||||
}
|
||||
|
||||
unsafe impl Send for SpanLocation {}
|
||||
unsafe impl Sync for SpanLocation {}
|
||||
|
||||
/// Instrumentation for timed regions, spans or zones of execution.
|
||||
impl Client {
|
||||
/// Start a new Tracy span/zone.
|
||||
///
|
||||
/// In order to obtain a [`SpanLocation`] value to provide to this function use the
|
||||
/// [`span_location!`](crate::span_location) macro.
|
||||
///
|
||||
/// Specifying a non-zero `callstack_depth` will enable collection of callstack for this
|
||||
/// message. The number provided will limit the number of call frames collected. Note that
|
||||
/// enabling callstack collection introduces a non-trivial amount of overhead to this call. On
|
||||
/// some systems this value may be clamped to a maximum value supported by the target.
|
||||
///
|
||||
/// The [`span!`](crate::span!) macro is a convenience wrapper over this method.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// In the following example the span is created with the location at which the
|
||||
/// `span_location!` macro appears and will measure the execution of the 100ms long sleep.
|
||||
///
|
||||
/// ```rust
|
||||
/// use tracy_client::{Client, span_location};
|
||||
/// let client = Client::start();
|
||||
/// {
|
||||
/// let _span = client.span(span_location!("sleeping"), 100);
|
||||
/// std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
/// } // _span ends
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn span(self, loc: &'static SpanLocation, callstack_depth: u16) -> Span {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
let zone = if callstack_depth == 0 {
|
||||
sys::___tracy_emit_zone_begin(&loc.data, 1)
|
||||
} else {
|
||||
let stack_depth = adjust_stack_depth(callstack_depth).into();
|
||||
sys::___tracy_emit_zone_begin_callstack(&loc.data, stack_depth, 1)
|
||||
};
|
||||
Span {
|
||||
client: self,
|
||||
zone,
|
||||
_no_send_sync: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "enable"))]
|
||||
Span {
|
||||
_no_send_sync: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Start a new Tracy span/zone.
|
||||
///
|
||||
/// This function allocates the span information on the heap until it is read out by the
|
||||
/// profiler. Prefer the [`Client::span`] as a allocation-free and faster alternative when
|
||||
/// possible.
|
||||
///
|
||||
/// Specifying a non-zero `callstack_depth` will enable collection of callstack for this
|
||||
/// message. The number provided will limit the number of call frames collected. Note that
|
||||
/// enabling callstack collection introduces a non-trivial amount of overhead to this call. On
|
||||
/// some systems this value may be clamped to a maximum value supported by the target.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// In the following example the span is created with custom span source data and will measure
|
||||
/// the execution of the 100ms long sleep.
|
||||
///
|
||||
/// ```rust
|
||||
/// use tracy_client::Client;
|
||||
/// let client = Client::start();
|
||||
/// {
|
||||
/// let _span = client.span_alloc(Some("hello"), "my_function", "hello.rs", 42, 100);
|
||||
/// std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
/// } // _span ends
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn span_alloc(
|
||||
self,
|
||||
name: Option<&str>,
|
||||
function: &str,
|
||||
file: &str,
|
||||
line: u32,
|
||||
callstack_depth: u16,
|
||||
) -> Span {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
let loc = sys::___tracy_alloc_srcloc_name(
|
||||
line,
|
||||
file.as_ptr().cast(),
|
||||
file.len(),
|
||||
function.as_ptr().cast(),
|
||||
function.len(),
|
||||
name.map(|n| n.as_ptr().cast()).unwrap_or(std::ptr::null()),
|
||||
name.unwrap_or("").len(),
|
||||
);
|
||||
let zone = if callstack_depth == 0 {
|
||||
sys::___tracy_emit_zone_begin_alloc(loc, 1)
|
||||
} else {
|
||||
let stack_depth = adjust_stack_depth(callstack_depth).into();
|
||||
sys::___tracy_emit_zone_begin_alloc_callstack(loc, stack_depth, 1)
|
||||
};
|
||||
Span {
|
||||
client: self,
|
||||
zone,
|
||||
_no_send_sync: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "enable"))]
|
||||
Span {
|
||||
_no_send_sync: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Span {
|
||||
/// Emit a numeric value associated with this span.
|
||||
pub fn emit_value(&self, value: u64) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
// SAFE: the only way to construct `Span` is by creating a valid tracy zone context.
|
||||
sys::___tracy_emit_zone_value(self.zone, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit some text associated with this span.
|
||||
pub fn emit_text(&self, text: &str) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
// SAFE: the only way to construct `Span` is by creating a valid tracy zone context.
|
||||
sys::___tracy_emit_zone_text(self.zone, text.as_ptr().cast(), text.len());
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit a color associated with this span.
|
||||
pub fn emit_color(&self, color: u32) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
// SAFE: the only way to construct `Span` is by creating a valid tracy zone context.
|
||||
// TODO: verify if we need to shift by 8 or not...?
|
||||
sys::___tracy_emit_zone_color(self.zone, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Span {
|
||||
fn drop(&mut self) {
|
||||
#[cfg(feature = "enable")]
|
||||
unsafe {
|
||||
// SAFE: The only way to construct `Span` is by creating a valid tracy zone context. We
|
||||
// also still have an owned Client handle.
|
||||
sys::___tracy_emit_zone_end(self.zone);
|
||||
std::convert::identity(&self.client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a <code>&'static [SpanLocation]</code>.
|
||||
///
|
||||
/// The returned `SpanLocation` is allocated statically and is cached between invocations. This
|
||||
/// `SpanLocation` will refer to the file and line at which this macro has been invoked, as well as
|
||||
/// to the item containing this macro invocation.
|
||||
///
|
||||
/// The resulting value may be used as an argument for the [`Client::span`] method.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// let location: &'static tracy_client::SpanLocation = tracy_client::span_location!("some name");
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! span_location {
|
||||
() => {{
|
||||
struct S;
|
||||
// String processing in `const` when, Oli?
|
||||
static LOC: $crate::internal::Lazy<$crate::internal::SpanLocation> =
|
||||
$crate::internal::Lazy::new(|| {
|
||||
$crate::internal::make_span_location(
|
||||
$crate::internal::type_name::<S>(),
|
||||
$crate::internal::null(),
|
||||
concat!(file!(), "\0").as_ptr(),
|
||||
line!(),
|
||||
)
|
||||
});
|
||||
&*LOC
|
||||
}};
|
||||
($name: expr) => {{
|
||||
struct S;
|
||||
// String processing in `const` when, Oli?
|
||||
static LOC: $crate::internal::Lazy<$crate::internal::SpanLocation> =
|
||||
$crate::internal::Lazy::new(|| {
|
||||
$crate::internal::make_span_location(
|
||||
$crate::internal::type_name::<S>(),
|
||||
concat!($name, "\0").as_ptr(),
|
||||
concat!(file!(), "\0").as_ptr(),
|
||||
line!(),
|
||||
)
|
||||
});
|
||||
&*LOC
|
||||
}};
|
||||
}
|
||||
|
||||
/// Start a new Tracy span with function, file, and line determined automatically.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// `span!` will panic if the Client isn't running at the time this macro is invoked.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Begin a span region, which will be terminated once `_span` goes out of scope:
|
||||
///
|
||||
/// ```
|
||||
/// use tracy_client::{Client, span};
|
||||
/// # let _client = tracy_client::Client::start();
|
||||
/// let _span = span!("some span");
|
||||
/// ```
|
||||
///
|
||||
/// It is also possible to enable collection of the callstack by specifying a limit of call stack
|
||||
/// frames to record:
|
||||
///
|
||||
/// ```
|
||||
/// use tracy_client::span;
|
||||
/// # let _client = tracy_client::Client::start();
|
||||
/// let _span = span!("some span", 32);
|
||||
/// ```
|
||||
///
|
||||
/// Note, however, that collecting callstack introduces a non-trivial overhead at the point of
|
||||
/// instrumentation.
|
||||
#[macro_export]
|
||||
macro_rules! span {
|
||||
() => {
|
||||
$crate::Client::running()
|
||||
.expect("span! without a running Client")
|
||||
.span($crate::span_location!(), 0)
|
||||
};
|
||||
($name: expr) => {
|
||||
$crate::span!($name, 0)
|
||||
};
|
||||
($name: expr, $callstack_depth: expr) => {{
|
||||
let location = $crate::span_location!($name);
|
||||
$crate::Client::running()
|
||||
.expect("span! without a running Client")
|
||||
.span(location, $callstack_depth)
|
||||
}};
|
||||
}
|
||||
167
third-party/vendor/tracy-client/src/state.rs
vendored
Normal file
167
third-party/vendor/tracy-client/src/state.rs
vendored
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
use crate::Client;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
/// Enabling `Tracy` when it is already enabled, or Disabling when it is already disabled will
|
||||
/// cause applications to crash. I personally think it would be better if this was a sort-of
|
||||
/// reference counted kind-of thing so you could enable as many times as you wish and disable
|
||||
/// just as many times without any reprecursions. At the very least this could significantly
|
||||
/// help tests.
|
||||
///
|
||||
/// We can also try to implement something like this ourselves. To do this we'd want to track 4
|
||||
/// states that construct a following finite state machine:
|
||||
///
|
||||
/// ```text
|
||||
/// 0 = disabled -> 1 = enabling
|
||||
/// ^ v
|
||||
/// 3 = disabling <- 2 = enabled
|
||||
/// ```
|
||||
///
|
||||
/// And also include a reference count somewhere in there. Something we can throw in a static
|
||||
/// would be ideal.
|
||||
///
|
||||
/// Alas, Tracy's extensive use of thread-local storage presents us with another problem – we must
|
||||
/// start up and shut down the client within the same thread. A most straightforward soution for
|
||||
/// that would be to run a separate thread that would be dedicated entirely to just starting up and
|
||||
/// shutting down the profiler.
|
||||
///
|
||||
/// All that seems like a major pain to implement, and so we’ll punt on disabling entirely until
|
||||
/// somebody comes with a good use-case warranting that sort of complexity.
|
||||
#[cfg(feature = "enable")]
|
||||
#[cfg(not(loom))]
|
||||
static CLIENT_STATE: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
|
||||
#[cfg(loom)]
|
||||
loom::lazy_static! {
|
||||
static ref CLIENT_STATE: loom::sync::atomic::AtomicUsize =
|
||||
loom::sync::atomic::AtomicUsize::new(0);
|
||||
}
|
||||
|
||||
#[cfg(feature = "enable")]
|
||||
const STATE_STEP: usize = 1; // Move forward by 1 step in the FSM
|
||||
#[cfg(feature = "enable")]
|
||||
const STATE_DISABLED: usize = 0;
|
||||
#[cfg(feature = "enable")]
|
||||
const STATE_ENABLING: usize = STATE_DISABLED + STATE_STEP;
|
||||
#[cfg(feature = "enable")]
|
||||
const STATE_ENABLED: usize = STATE_ENABLING + STATE_STEP;
|
||||
|
||||
#[cfg(feature = "enable")]
|
||||
#[inline(always)]
|
||||
fn spin_loop() {
|
||||
#[cfg(loom)]
|
||||
loom::thread::yield_now();
|
||||
#[cfg(not(loom))]
|
||||
std::hint::spin_loop();
|
||||
}
|
||||
|
||||
/// Client initialization and lifetime management.
|
||||
impl Client {
|
||||
/// Start the client.
|
||||
///
|
||||
/// The client must be started with this function before any instrumentation is invoked
|
||||
/// anywhere in the process. This function can be called multiple times to obtain multiple
|
||||
/// `Client` values.
|
||||
///
|
||||
/// The underying client implementation will be started up only if it wasn't already running
|
||||
/// yet.
|
||||
///
|
||||
/// Note that there currently isn't a mechanism to stop the client once it has been started.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// // fn main() {
|
||||
/// let _client = tracy_client::Client::start();
|
||||
/// // ...
|
||||
/// // }
|
||||
/// ```
|
||||
pub fn start() -> Self {
|
||||
#[cfg(feature = "enable")]
|
||||
{
|
||||
let mut old_state = CLIENT_STATE.load(Ordering::Relaxed);
|
||||
loop {
|
||||
match old_state {
|
||||
STATE_ENABLED => return Client(()),
|
||||
STATE_ENABLING => {
|
||||
while !Self::is_running() {
|
||||
spin_loop();
|
||||
}
|
||||
return Client(());
|
||||
}
|
||||
STATE_DISABLED => {
|
||||
let result = CLIENT_STATE.compare_exchange_weak(
|
||||
old_state,
|
||||
STATE_ENABLING,
|
||||
Ordering::Relaxed,
|
||||
Ordering::Relaxed,
|
||||
);
|
||||
if let Err(next_old_state) = result {
|
||||
old_state = next_old_state;
|
||||
continue;
|
||||
} else {
|
||||
unsafe {
|
||||
// SAFE: This function must not be called if the profiler has
|
||||
// already been enabled. While in practice calling this function
|
||||
// multiple times will only serve to trigger an assertion, we
|
||||
// cannot exactly rely on this, since it is an undocumented
|
||||
// behaviour and the upstream might very well just decide to invoke
|
||||
// UB instead. In the case there are multiple copies of
|
||||
// `tracy-client` this invariant is not actually maintained, but
|
||||
// otherwise this is sound due to the `ENABLE_STATE` that we
|
||||
// manage.
|
||||
//
|
||||
// TODO: we _could_ define `ENABLE_STATE` in the `-sys` crate...
|
||||
sys::___tracy_startup_profiler();
|
||||
CLIENT_STATE.store(STATE_ENABLED, Ordering::Release);
|
||||
return Client(());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "enable"))]
|
||||
Client(())
|
||||
}
|
||||
|
||||
/// Obtain a client handle, but only if the client is already running.
|
||||
#[inline(always)]
|
||||
pub fn running() -> Option<Self> {
|
||||
if Self::is_running() {
|
||||
Some(Client(()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Is the client already running?
|
||||
#[inline(always)]
|
||||
pub fn is_running() -> bool {
|
||||
#[cfg(feature = "enable")]
|
||||
return CLIENT_STATE.load(Ordering::Relaxed) == STATE_ENABLED;
|
||||
#[cfg(not(feature = "enable"))]
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Client {
|
||||
/// A cheaper alternative to [`Client::start`] or [`Client::running`] when there is already a
|
||||
/// handle handy.
|
||||
#[inline(always)]
|
||||
fn clone(&self) -> Self {
|
||||
// We already know that the state is `ENABLED`, no need to check.
|
||||
Client(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, feature = "enable"))]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn state_transitions() {
|
||||
assert_eq!(0, STATE_DISABLED);
|
||||
assert_eq!(STATE_DISABLED.wrapping_add(STATE_STEP), STATE_ENABLING);
|
||||
assert_eq!(STATE_ENABLING.wrapping_add(STATE_STEP), STATE_ENABLED);
|
||||
}
|
||||
}
|
||||
76
third-party/vendor/tracy-client/tests/loom.rs
vendored
Normal file
76
third-party/vendor/tracy-client/tests/loom.rs
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#[cfg(loom)]
|
||||
mod loom {
|
||||
|
||||
use loom::thread;
|
||||
use tracy_client::Client;
|
||||
|
||||
fn model<F>(f: F)
|
||||
where
|
||||
F: Fn() + Sync + Send + 'static,
|
||||
{
|
||||
#[cfg(not(loom))]
|
||||
{
|
||||
f()
|
||||
}
|
||||
#[cfg(loom)]
|
||||
{
|
||||
let mut builder = loom::model::Builder::new();
|
||||
builder.preemption_bound = Some(3);
|
||||
builder.check(f)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
model(|| {
|
||||
let client = Client::start();
|
||||
assert!(Client::is_running());
|
||||
drop(client);
|
||||
unsafe {
|
||||
___tracy_shutdown_profiler();
|
||||
}
|
||||
});
|
||||
|
||||
model(|| {
|
||||
let t1 = thread::spawn(|| {
|
||||
let client = Client::start();
|
||||
assert!(Client::is_running());
|
||||
drop(client);
|
||||
});
|
||||
let client = Client::start();
|
||||
assert!(Client::is_running());
|
||||
drop(client);
|
||||
t1.join().unwrap();
|
||||
unsafe {
|
||||
___tracy_shutdown_profiler();
|
||||
}
|
||||
});
|
||||
|
||||
model(|| {
|
||||
let t1 = thread::spawn(move || {
|
||||
let client = Client::start();
|
||||
assert!(Client::is_running());
|
||||
let client2 = client.clone();
|
||||
assert!(Client::is_running());
|
||||
drop(client);
|
||||
assert!(Client::is_running());
|
||||
drop(client2);
|
||||
});
|
||||
let client = Client::start();
|
||||
assert!(Client::is_running());
|
||||
let client2 = client.clone();
|
||||
assert!(Client::is_running());
|
||||
drop(client2);
|
||||
assert!(Client::is_running());
|
||||
drop(client);
|
||||
t1.join().unwrap();
|
||||
unsafe {
|
||||
___tracy_shutdown_profiler();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[cfg(loom)]
|
||||
loom::main();
|
||||
}
|
||||
124
third-party/vendor/tracy-client/tests/tests.rs
vendored
Normal file
124
third-party/vendor/tracy-client/tests/tests.rs
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
use tracy_client::*;
|
||||
|
||||
#[global_allocator]
|
||||
static GLOBAL: ProfiledAllocator<std::alloc::System> =
|
||||
ProfiledAllocator::new(std::alloc::System, 100);
|
||||
|
||||
fn basic_zone() {
|
||||
let client = Client::start();
|
||||
let span = client.span(span_location!("basic_zone"), 100);
|
||||
span.emit_value(42);
|
||||
span.emit_text("some text");
|
||||
for i in 322..420 {
|
||||
span.emit_value(i);
|
||||
}
|
||||
}
|
||||
|
||||
fn alloc_zone() {
|
||||
let client = Client::start();
|
||||
let span = client.span_alloc(Some("alloc_zone"), "alloc_zone", file!(), line!(), 100);
|
||||
span.emit_value(42);
|
||||
span.emit_color(0x00FF0000);
|
||||
span.emit_text("some text");
|
||||
}
|
||||
|
||||
fn finish_frameset() {
|
||||
let client = Client::start();
|
||||
for _ in 0..10 {
|
||||
client.frame_mark();
|
||||
}
|
||||
frame_mark();
|
||||
}
|
||||
|
||||
fn finish_secondary_frameset() {
|
||||
let client = Client::start();
|
||||
for _ in 0..5 {
|
||||
client.secondary_frame_mark(frame_name!("secondary frame"));
|
||||
}
|
||||
secondary_frame_mark!("secondary frame macro");
|
||||
}
|
||||
|
||||
fn non_continuous_frameset() {
|
||||
const NON_CONTINUOUS: FrameName = frame_name!("non continuous");
|
||||
let client = Client::start();
|
||||
client.non_continuous_frame(NON_CONTINUOUS);
|
||||
non_continuous_frame!("non continuous macro");
|
||||
}
|
||||
|
||||
fn plot_something() {
|
||||
static TEMPERATURE: PlotName = plot_name!("temperature");
|
||||
let client = Client::start();
|
||||
for i in 0..10 {
|
||||
client.plot(TEMPERATURE, i as f64);
|
||||
}
|
||||
|
||||
plot!("temperature", 42.0);
|
||||
}
|
||||
|
||||
fn allocations() {
|
||||
let mut strings = Vec::new();
|
||||
for i in 0..100 {
|
||||
strings.push(format!("{:?}", i));
|
||||
}
|
||||
}
|
||||
|
||||
fn fib(i: u16) -> u64 {
|
||||
let span = span!();
|
||||
span.emit_text(&format!("fib({})", i));
|
||||
let result = match i {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
_ => fib(i - 1) + fib(i - 2),
|
||||
};
|
||||
span.emit_value(result);
|
||||
result
|
||||
}
|
||||
|
||||
fn message() {
|
||||
let client = Client::start();
|
||||
client.message("test message", 100);
|
||||
client.message("test message without stack", 0);
|
||||
}
|
||||
|
||||
fn tls_confusion() {
|
||||
let client = Client::start();
|
||||
let t1 = std::thread::spawn(move || {
|
||||
drop(client);
|
||||
});
|
||||
let _ = t1.join();
|
||||
let _ = Client::start();
|
||||
}
|
||||
|
||||
fn set_thread_name() {
|
||||
let _client = Client::start();
|
||||
set_thread_name!("test thread");
|
||||
}
|
||||
|
||||
fn nameless_span() {
|
||||
let client = Client::start();
|
||||
span!();
|
||||
client.span_alloc(None, "nameless_span", file!(), line!(), 0);
|
||||
set_thread_name!("test thread");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[cfg(not(loom))]
|
||||
{
|
||||
basic_zone();
|
||||
alloc_zone();
|
||||
finish_frameset();
|
||||
finish_secondary_frameset();
|
||||
non_continuous_frameset();
|
||||
plot_something();
|
||||
message();
|
||||
allocations();
|
||||
tls_confusion();
|
||||
nameless_span();
|
||||
let thread = std::thread::spawn(|| {
|
||||
let _client = Client::start();
|
||||
fib(25);
|
||||
});
|
||||
thread.join().unwrap();
|
||||
set_thread_name();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue