Skip to content

Commit 42a81b9

Browse files
committed
WIP: field reflection example
Signed-off-by: Boqun Feng <[email protected]>
1 parent f5a39b7 commit 42a81b9

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

examples/field_type.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
use field_projection::{
2+
compat::HasFields,
3+
field_of,
4+
marker::{Field, UnalignedField},
5+
};
6+
7+
use core::ptr::null_mut;
8+
use std::sync::Arc;
9+
10+
// Workqueue:
11+
12+
pub struct Work {
13+
state: usize,
14+
func: Option<fn(*mut Work)>,
15+
next: *mut Work,
16+
}
17+
18+
pub trait WorkItem<F: Field> {
19+
fn run(&self);
20+
}
21+
22+
impl WorkItem<field_of!(Foo, work)> for Foo {
23+
fn run(&self) {
24+
println!("hello work");
25+
}
26+
}
27+
28+
impl WorkItem<field_of!(Foo, work2)> for Foo {
29+
fn run(&self) {
30+
println!("hello work2");
31+
}
32+
}
33+
34+
fn bridge<F: Field<Type = Work>>(ptr: *mut Work)
35+
where
36+
F::Base: WorkItem<F> + Sized,
37+
{
38+
let ptr = unsafe { ptr.byte_sub(F::OFFSET) }.cast::<F::Base>();
39+
40+
unsafe { &*ptr }.run();
41+
}
42+
43+
impl Work {
44+
// TODO: this should return PinInit.
45+
pub const unsafe fn new<F: Field<Type = Work>>() -> Self
46+
where
47+
F::Base: WorkItem<F> + Sized,
48+
{
49+
Self {
50+
state: 0,
51+
func: Some(bridge::<F>),
52+
next: null_mut(),
53+
}
54+
}
55+
}
56+
57+
#[derive(HasFields)]
58+
pub struct Foo {
59+
a: i32,
60+
b: i32,
61+
work: Work,
62+
work2: Work,
63+
}
64+
65+
impl Foo {
66+
pub fn new_arc(a: i32, b: i32) -> Arc<Self> {
67+
Arc::new(Self {
68+
a,
69+
b,
70+
work: unsafe { Work::new::<field_of!(Foo, work)>() },
71+
work2: unsafe { Work::new::<field_of!(Foo, work2)>() },
72+
})
73+
}
74+
}
75+
76+
pub trait WorkItemPointer<F: Field<Type = Work>>: Sized {
77+
// Simulates RawWorkItem
78+
fn into_work(self) -> *mut Work;
79+
80+
fn c_run(ptr: *mut Work);
81+
}
82+
83+
impl<T, F: Field<Base = T, Type = Work>> WorkItemPointer<F> for Arc<T>
84+
where
85+
T: WorkItem<F>,
86+
{
87+
fn into_work(self) -> *mut Work {
88+
let ptr = Arc::into_raw(self);
89+
unsafe { ptr.byte_add(F::OFFSET).cast_mut().cast() }
90+
}
91+
92+
fn c_run(ptr: *mut Work) {
93+
let ptr = unsafe { ptr.byte_sub(F::OFFSET).cast::<T>() };
94+
95+
let arc = unsafe { Arc::from_raw(ptr) };
96+
97+
arc.run();
98+
}
99+
}
100+
101+
/// # Safety
102+
///
103+
/// `work` must point to a valid pointer of `Work`.
104+
unsafe fn c_run_work(work: *mut Work) {
105+
if let Some(func) = unsafe { (*work).func } {
106+
func(work)
107+
}
108+
}
109+
110+
pub fn queue_work<F: Field<Base = T, Type = Work>, T: WorkItem<F>, P: WorkItemPointer<F>>(p: P) {
111+
// Simulate queue work and run
112+
let ptr = p.into_work();
113+
114+
// SAFETY: `ptr` is a valid pointer of `Work`.
115+
unsafe { c_run_work(ptr) };
116+
}
117+
118+
#[test]
119+
fn main() {
120+
let foo = Foo::new_arc(12, 42);
121+
let foo2 = Foo::new_arc(12, 42);
122+
123+
queue_work::<field_of!(Foo, work), _, _>(foo);
124+
queue_work::<field_of!(Foo, work2), _, _>(foo2);
125+
}

0 commit comments

Comments
 (0)