Skip to content

Commit a22d300

Browse files
authored
Merge pull request #57 from wesleywiser/store_info
Store some metadata about the profile in a reserved string table slot
2 parents 3e14f95 + 5b76a03 commit a22d300

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

measureme/src/profiler.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::file_header::{write_file_header, FILE_MAGIC_EVENT_STREAM};
22
use crate::raw_event::{RawEvent, Timestamp, TimestampKind};
33
use crate::serialization::SerializationSink;
4-
use crate::stringtable::{SerializableString, StringId, StringTableBuilder};
4+
use crate::stringtable::{METADATA_STRING_ID, SerializableString, StringId, StringTableBuilder};
55
use std::error::Error;
66
use std::path::{Path, PathBuf};
77
use std::sync::Arc;
@@ -42,11 +42,26 @@ impl<S: SerializationSink> Profiler<S> {
4242
Arc::new(S::from_path(&paths.string_index_file)?),
4343
);
4444

45-
Ok(Profiler {
45+
let profiler = Profiler {
4646
event_sink,
4747
string_table,
4848
start_time: Instant::now(),
49-
})
49+
};
50+
51+
let mut args = String::new();
52+
for arg in std::env::args() {
53+
args.push_str(&arg.escape_default().to_string());
54+
args.push(' ');
55+
}
56+
57+
profiler.string_table.alloc_metadata(&*format!(
58+
r#"{{ "start_time": {}, "process_id": {}, "cmd": "{}" }}"#,
59+
std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_nanos(),
60+
std::process::id(),
61+
args,
62+
));
63+
64+
Ok(profiler)
5065
}
5166

5267
#[inline(always)]

measureme/src/stringtable.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,23 @@
1111
//! content of its components. The content of a `TAG_STR_VAL` is its actual
1212
//! UTF-8 bytes. The content of a `TAG_STR_REF` is the contents of the entry
1313
//! it references.
14+
//!
15+
//! Each string is referred to via a `StringId`. `StringId`s may be generated in two ways:
16+
//! 1. Calling `StringTable::alloc()` which returns the `StringId` for the allocated string.
17+
//! 2. Calling `StringTable::alloc_with_reserved_id()` and `StringId::reserved()`.
18+
//!
19+
//! Reserved strings allow you to deduplicate strings by allocating a string once and then referring
20+
//! to it by id over and over. This is a useful trick for strings which are recorded many times and
21+
//! it can significantly reduce the size of profile trace files.
22+
//!
23+
//! `StringId`s are partitioned according to type:
24+
//!
25+
//! > [0 .. MAX_PRE_RESERVED_STRING_ID, METADATA_STRING_ID, .. ]
26+
//!
27+
//! From `0` to `MAX_PRE_RESERVED_STRING_ID` are the allowed values for reserved strings.
28+
//! After `MAX_PRE_RESERVED_STRING_ID`, there is one string id (`METADATA_STRING_ID`) which is used
29+
//! internally by `measureme` to record additional metadata about the profiling session.
30+
//! After `METADATA_STRING_ID` are all other `StringId` values.
1431
1532
use crate::file_header::{
1633
read_file_header, strip_file_header, write_file_header, FILE_MAGIC_STRINGTABLE_DATA,
@@ -47,13 +64,17 @@ const TAG_STR_VAL: u8 = 1;
4764
/// Marks a component that contains the ID of another string.
4865
const TAG_STR_REF: u8 = 2;
4966

67+
/// The maximum id value a prereserved string may be.
5068
const MAX_PRE_RESERVED_STRING_ID: u32 = std::u32::MAX / 2;
5169

70+
/// The id of the profile metadata string entry.
71+
pub(crate) const METADATA_STRING_ID: u32 = MAX_PRE_RESERVED_STRING_ID + 1;
72+
5273
/// Write-only version of the string table
5374
pub struct StringTableBuilder<S: SerializationSink> {
5475
data_sink: Arc<S>,
5576
index_sink: Arc<S>,
56-
id_counter: AtomicU32, // initialized to MAX_PRE_RESERVED_STRING_ID + 1
77+
id_counter: AtomicU32, // initialized to METADATA_STRING_ID + 1
5778
}
5879

5980
/// Anything that implements `SerializableString` can be written to a
@@ -129,7 +150,7 @@ impl<S: SerializationSink> StringTableBuilder<S> {
129150
StringTableBuilder {
130151
data_sink,
131152
index_sink,
132-
id_counter: AtomicU32::new(MAX_PRE_RESERVED_STRING_ID + 1),
153+
id_counter: AtomicU32::new(METADATA_STRING_ID + 1),
133154
}
134155
}
135156

@@ -144,10 +165,16 @@ impl<S: SerializationSink> StringTableBuilder<S> {
144165
id
145166
}
146167

168+
pub(crate) fn alloc_metadata<STR: SerializableString + ?Sized>(&self, s: &STR) -> StringId {
169+
let id = StringId(METADATA_STRING_ID);
170+
self.alloc_unchecked(id, s);
171+
id
172+
}
173+
147174
#[inline]
148175
pub fn alloc<STR: SerializableString + ?Sized>(&self, s: &STR) -> StringId {
149176
let id = StringId(self.id_counter.fetch_add(1, Ordering::SeqCst));
150-
debug_assert!(id.0 > MAX_PRE_RESERVED_STRING_ID);
177+
debug_assert!(id.0 > METADATA_STRING_ID);
151178
self.alloc_unchecked(id, s);
152179
id
153180
}

0 commit comments

Comments
 (0)