Skip to content

Commit e9761ca

Browse files
committed
[topo] Cleanup syntax, more docs, better benches.
1 parent 88b79ce commit e9761ca

File tree

9 files changed

+244
-168
lines changed

9 files changed

+244
-168
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ chashmap = "2"
1111
futures-preview = { version = "0.3.0-alpha.16", features = [ "async-await", "nightly" ] }
1212
once_cell = "0.2"
1313
parking_lot = "0.8"
14+
tokio-trace = "0.1"
1415
topo = { path = "topo" }
1516

1617
[dev-dependencies]

src/lib.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
//!
1818
//! TODO
1919
20-
#![deny(clippy::all, missing_docs)]
20+
#![deny(clippy::all, missing_docs, intra_doc_link_resolution_failure)]
2121
#![feature(async_await, gen_future)]
2222

2323
#[macro_use]
@@ -29,7 +29,7 @@ pub use {memo::*, state::*};
2929

3030
use {
3131
std::ops::Deref,
32-
topo::__trace::{field::debug, *},
32+
tokio_trace::{field::debug, *},
3333
};
3434

3535
/// Controls the iteration behavior of a runloop. The default of `OnWake` will leave the runloop
@@ -114,22 +114,25 @@ pub async fn runloop(mut root: impl FnMut(&state::Key<LoopBehavior>)) {
114114
let task_waker = RunLoopWaker(std::future::get_task_context(|c| c.waker().clone()));
115115

116116
let mut current_revision = Revision(0);
117-
let mut next_behavior = None;
117+
let mut next_behavior;
118118
loop {
119119
current_revision.0 += 1;
120120

121-
topo::root!(|| {
122-
let (_, behavior) = state!((), |()| LoopBehavior::default());
121+
topo::root!(
122+
{
123+
let (_, behavior) = state!((), |()| LoopBehavior::default());
123124

124-
// CALLER'S CODE IS CALLED HERE
125-
root(&behavior);
125+
// CALLER'S CODE IS CALLED HERE
126+
root(&behavior);
126127

127-
// stash the write key for ourselves for reading after exiting this call
128-
next_behavior = behavior.flushed().read();
129-
}, Env {
130-
RunLoopWaker => task_waker.clone(),
131-
Revision => current_revision
132-
});
128+
// stash the write key for ourselves for reading after exiting this call
129+
next_behavior = behavior.flushed().read();
130+
},
131+
env! {
132+
RunLoopWaker => task_waker.clone(),
133+
Revision => current_revision,
134+
}
135+
);
133136

134137
match next_behavior.as_ref().unwrap().deref() {
135138
LoopBehavior::OnWake => {

src/memo.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use {
55
any::{Any, TypeId},
66
sync::Arc,
77
},
8-
topo::topo,
98
};
109

1110
/// Memoize the provided function at the bound callsite, invalidating previous results only if
@@ -15,7 +14,7 @@ use {
1514
/// it places a significant constraint on the initializers themselves to only capture `Clone` values
1615
/// or to avoid mutating its captures to implement `Fn`. Instead we require that closures accept
1716
/// the memoized argument by reference rather than by value.
18-
#[topo]
17+
#[topo::bound]
1918
pub fn memo<Arg, Init, Output>(arg: Arg, initializer: Init) -> Output
2019
where
2120
Arg: PartialEq + Send + Sync + 'static,
@@ -55,7 +54,7 @@ where
5554
mod tests {
5655
use {
5756
crate::{memo::*, LoopBehavior, Revision},
58-
topo::__trace::*,
57+
tokio_trace::*,
5958
};
6059

6160
#[runtime::test]

src/state.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@ use {
55
ops::Deref,
66
sync::{Arc, Weak},
77
},
8-
topo::topo,
8+
topo::bound,
99
};
1010

1111
// TODO state tests
1212

13-
/// Root a state variable at this callsite, returning an up-to-date [`Commit`] of its value and
14-
/// a unique [`Key`] which can be used to commit new values to the variable.
15-
#[topo]
1613
// TODO: proc macro should allow topo functions to declare `arg` optional with a default to
1714
// which the macro can desugar invocations, so you can pass a init closure only.
1815
// TODO: move arg after initializer
16+
17+
/// Root a state variable at this callsite, returning an up-to-date [`Commit`] of its value and
18+
/// a unique [`Key`] which can be used to commit new values to the variable.
19+
#[bound]
1920
pub fn state<Arg, Init, Output>(arg: Arg, initializer: Init) -> (Commit<Output>, Key<Output>)
2021
where
2122
Arg: PartialEq + Send + Sync + 'static,

topo/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ edition = "2018"
66

77
[dependencies]
88
owning_ref = "0.4"
9-
tokio-trace = { version = "0.1", features = ["log"] }
109
topo-macro = { path = "macro" }
1110

1211
[dev-dependencies]

topo/benches/simple.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,46 @@ use criterion::{black_box, Criterion, ParameterizedBenchmark};
55

66
fn empty_env(c: &mut Criterion) {
77
c.bench_function("call empty env", |b| {
8-
b.iter(|| black_box(topo::call!(|| topo::Id::current())))
8+
b.iter(|| black_box(topo::call!(topo::Id::current())))
99
});
1010
}
1111

1212
fn create_small_env(c: &mut Criterion) {
1313
c.bench_function("call create small env", |b| {
1414
b.iter(|| {
15-
black_box(topo::call!(|| topo::Id::current(), Env {
16-
u128 => 10
17-
}))
15+
black_box(topo::call!(
16+
topo::Id::current(),
17+
env! {
18+
u128 => 10,
19+
}
20+
))
1821
});
1922
});
2023
}
2124

25+
fn call_small_env(c: &mut Criterion) {
26+
c.bench_function("call within small env", |b| {
27+
topo::call!(
28+
b.iter(|| {
29+
black_box(topo::call!(topo::Id::current()));
30+
}),
31+
env! {
32+
u128 => 10,
33+
}
34+
)
35+
});
36+
}
37+
2238
#[allow(clippy::trivially_copy_pass_by_ref)]
2339
fn topo_bench(b: &mut criterion::Bencher, depth: &usize) {
2440
macro_rules! mk {
2541
(go $depth_spec:ident) => {
26-
topo::call!(|| {
42+
topo::call!({
2743
mk!(pass $depth_spec 0);
28-
}, Env { u128 => 10 });
44+
}, env! { u128 => 10, });
2945
};
3046
(pass $depth_spec:ident $call_depth:expr) => {
31-
topo::call!(|| {
47+
topo::call!({
3248
mk!(cur $depth_spec ($call_depth + 1));
3349
});
3450
};
@@ -91,7 +107,7 @@ fn topo_bench(b: &mut criterion::Bencher, depth: &usize) {
91107
}
92108
}
93109

94-
fn enter_small_env(c: &mut Criterion) {
110+
fn from_small_env(c: &mut Criterion) {
95111
c.bench(
96112
"topo fns",
97113
ParameterizedBenchmark::new(
@@ -102,5 +118,11 @@ fn enter_small_env(c: &mut Criterion) {
102118
);
103119
}
104120

105-
criterion_group!(benches, empty_env, create_small_env, enter_small_env);
106-
criterion_main!(benches);
121+
criterion::criterion_group!(
122+
benches,
123+
empty_env,
124+
create_small_env,
125+
from_small_env,
126+
call_small_env
127+
);
128+
criterion::criterion_main!(benches);

topo/macro/src/lib.rs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,13 @@
55
extern crate proc_macro;
66
use {proc_macro::TokenStream, syn::export::TokenStream2};
77

8-
/// Transforms a function declaration into a topological function invoked with macro syntax.
8+
/// Transforms a function declaration into a topological function invoked with macro syntax to
9+
/// *bind* its call tree's (sub)topology to the parent topology.
910
///
1011
/// A macro transformation is used to capture unique callsite information from the invoking
1112
/// function. In the current implementation, we synthesize a unique [`std::any::TypeId`] at each
1213
/// callsite which can be used to identify the chain of topological invocations.
1314
///
14-
/// ```
15-
/// # use topo::topo;
16-
/// #[topo]
17-
/// fn print_id() {
18-
/// // this will print something different depending
19-
/// // on location in the call topology
20-
/// println!("{:?}", topo::Id::current());
21-
/// }
22-
///
23-
/// print_id!();
24-
/// print_id!();
25-
/// ```
26-
///
2715
/// ## Implications of using macros
2816
///
2917
/// Upside: Because topological function calls are a bit more expensive than normal function calls,
@@ -49,7 +37,7 @@ use {proc_macro::TokenStream, syn::export::TokenStream2};
4937
///
5038
/// TODO expand
5139
#[proc_macro_attribute]
52-
pub fn topo(_attrs: TokenStream, input: TokenStream) -> TokenStream {
40+
pub fn bound(_attrs: TokenStream, input: TokenStream) -> TokenStream {
5341
let mut input_fn: syn::ItemFn = syn::parse_macro_input!(input);
5442

5543
let tmp = std::mem::replace(&mut input_fn.attrs, Vec::new());
@@ -105,7 +93,6 @@ fn docs_fn_signature(input_fn: &syn::ItemFn) -> TokenStream2 {
10593
decl: input_fn.decl.clone(),
10694
block: Box::new(syn::Block {
10795
brace_token: syn::token::Brace {
108-
// we
10996
span: proc_macro::Span::call_site().into(),
11097
},
11198
stmts: vec![],

0 commit comments

Comments
 (0)