ptest/
main.rs

1use std::fmt::{Debug, Display};
2
3use clap::Parser;
4use miette::{IntoDiagnostic, Result};
5use naming::GetFlags;
6use tracing::Level;
7use twizzler::{
8    Invariant,
9    alloc::{
10        arena::{ArenaAllocator, ArenaObject},
11        invbox::InvBox,
12    },
13    collections::vec::{VecObject, VecObjectAlloc},
14    marker::Invariant,
15    object::{MapFlags, ObjID, Object, ObjectBuilder},
16};
17use twizzler_abi::syscall::sys_object_ctrl;
18use twizzler_rt_abi::{error::TwzError, object::ObjectHandle};
19
20#[allow(dead_code)]
21#[derive(Invariant)]
22struct Foo {
23    data: InvBox<u32, ArenaAllocator>,
24    local_data: u32,
25}
26
27impl Debug for Foo {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        f.debug_struct("Foo")
30            .field("local_data", &self.local_data)
31            .field("data (ptr)", &self.data.global())
32            .field("data (val)", &*self.data.resolve())
33            .finish()
34    }
35}
36
37impl Display for Foo {
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        write!(
40            f,
41            "Foo ({:p}): local {}, ptr: {:x} :: ",
42            self,
43            &self.local_data,
44            &self.data.as_ptr().raw(),
45        )?;
46        write!(f, "{}", &*self.data.resolve())
47    }
48}
49
50fn create_arena() -> Result<ArenaObject> {
51    let obj = ObjectBuilder::default().persist();
52    ArenaObject::new(obj).into_diagnostic()
53}
54
55fn open_arena(id: ObjID) -> Result<ArenaObject> {
56    ArenaObject::from_objid(id).into_diagnostic()
57}
58
59fn create_vector_object<T: Debug + Invariant>() -> Result<VecObject<T, VecObjectAlloc>> {
60    let obj = ObjectBuilder::default().persist();
61    VecObject::<T, VecObjectAlloc>::new(obj).into_diagnostic()
62}
63
64fn open_vector_object<T: Debug + Invariant>(id: ObjID) -> Result<VecObject<T, VecObjectAlloc>> {
65    Ok(VecObject::from(
66        Object::map(id, MapFlags::PERSIST | MapFlags::READ | MapFlags::WRITE).into_diagnostic()?,
67    ))
68}
69
70#[derive(clap::Parser, Clone, Copy, Debug)]
71struct Cli {
72    sub: SubCommand,
73    #[clap(default_value = "u32")]
74    ty: VecTy,
75}
76
77#[derive(clap::ValueEnum, clap::Parser, Clone, Copy, Debug)]
78enum VecTy {
79    U32,
80    Foo,
81}
82
83#[derive(clap::ValueEnum, clap::Subcommand, Clone, Copy, Debug)]
84enum SubCommand {
85    New,
86    Push,
87    Append,
88    Read,
89    Hw,
90    Rdb,
91    Preload,
92}
93
94fn open_or_create_arena() -> Result<ArenaObject> {
95    let mut nh = naming::dynamic_naming_factory().unwrap();
96    let name = format!("/data/ptest-arena");
97    let vo = if let Ok(node) = nh.get(&name, GetFlags::empty()) {
98        println!("reopened-arena: {:?}", node.id);
99        open_arena(node.id)
100    } else {
101        let vo = create_arena()?;
102        println!("new-arena: {:?}", vo.object().id());
103        let _ = nh.remove(&name);
104        nh.put(&name, vo.object().id()).into_diagnostic()?;
105        Ok(vo)
106    };
107    vo
108}
109fn open_or_create_vector_object<T: Debug + Invariant>(
110    name: &str,
111) -> Result<VecObject<T, VecObjectAlloc>> {
112    let mut nh = naming::dynamic_naming_factory().unwrap();
113    let name = format!("/data/ptest-obj-{}", name);
114    let vo = if let Ok(node) = nh.get(&name, GetFlags::empty()) {
115        println!("reopened: {:?}", node.id);
116        open_vector_object::<T>(node.id)
117    } else {
118        let vo = create_vector_object::<T>()?;
119        println!("new: {:?}", vo.object().id());
120        let _ = nh.remove(&name);
121        nh.put(&name, vo.object().id()).into_diagnostic()?;
122        Ok(vo)
123    };
124    vo
125}
126
127impl Foo {
128    fn new_in(
129        place: impl AsRef<ObjectHandle>,
130        val: u32,
131        alloc: ArenaAllocator,
132    ) -> Result<Self, TwzError> {
133        Ok(Self {
134            data: InvBox::new_in(place, val, alloc)?,
135            local_data: val,
136        })
137    }
138}
139
140fn do_push_foo(mut vo: VecObject<Foo, VecObjectAlloc>, arena: ArenaObject) {
141    let val = vo.len() as u32;
142    vo.push_ctor(|r| {
143        let foo = Foo::new_in(&r, val, arena.allocator())?;
144        Ok(r.write(foo))
145    })
146    .unwrap();
147}
148
149fn do_append_foo(mut vo: VecObject<Foo, VecObjectAlloc>, arena: ArenaObject) {
150    for i in 0..8 {
151        tracing::info!("PUSH {}", i);
152        vo.push_ctor(|r| {
153            let foo = Foo::new_in(&r, i, arena.allocator())?;
154            Ok(r.write(foo))
155        })
156        .unwrap();
157        tracing::info!("DONE: {}", i);
158    }
159}
160
161fn do_push(vo: VecObject<u32, VecObjectAlloc>) {
162    let mut vo = vo;
163    vo.push(vo.len() as u32).unwrap();
164}
165
166fn do_append(vo: VecObject<u32, VecObjectAlloc>) {
167    let mut vo = vo;
168    for i in 0..100 {
169        vo.push(i).unwrap();
170    }
171}
172
173fn do_read<T: Debug + Invariant + Display>(vo: VecObject<T, VecObjectAlloc>) {
174    for i in vo.iter().enumerate() {
175        println!("entry {}: {}", i.0, i.1);
176    }
177}
178
179#[link(name = "c")]
180unsafe extern "C" {}
181fn main() {
182    tracing::subscriber::set_global_default(
183        tracing_subscriber::FmtSubscriber::builder()
184            .with_max_level(Level::INFO)
185            .finish(),
186    )
187    .unwrap();
188    let cli = Cli::parse();
189    println!("==> {:?}", cli);
190
191    let mut nh = naming::dynamic_naming_factory().unwrap();
192    match cli.sub {
193        SubCommand::Hw => {
194            let top = hwlocality::topology::Topology::new().unwrap();
195            println!("{:#?}", top);
196            let cpus = top.complete_cpuset();
197            println!("==> {:?}", cpus);
198        }
199        SubCommand::New => match cli.ty {
200            VecTy::U32 => {
201                let _ = nh.remove("/data/ptest-obj-u32");
202                let vo = create_vector_object::<u32>().unwrap();
203                println!("new: {:?}", vo.object().id());
204                nh.put("/data/ptest-obj-u32", vo.object().id()).unwrap();
205            }
206            VecTy::Foo => {
207                let _ = nh.remove("/data/ptest-obj-foo");
208                let _ = nh.remove("/data/ptest-arena");
209                let vo = create_vector_object::<u32>().unwrap();
210                println!("new: {:?}", vo.object().id());
211                nh.put("/data/ptest-obj-foo", vo.object().id()).unwrap();
212
213                let vo = create_arena().unwrap();
214                println!("new arena: {:?}", vo.object().id());
215                nh.put("/data/ptest-arena", vo.object().id()).unwrap();
216            }
217        },
218        SubCommand::Push => match cli.ty {
219            VecTy::U32 => {
220                let vo = open_or_create_vector_object::<u32>("u32").unwrap();
221                let start = std::time::Instant::now();
222                do_push(vo);
223                let end = std::time::Instant::now();
224                println!("done!: {:?}", end - start);
225            }
226            VecTy::Foo => {
227                let vo = open_or_create_vector_object::<Foo>("foo").unwrap();
228                let arena = open_or_create_arena().unwrap();
229                let start = std::time::Instant::now();
230                do_push_foo(vo, arena);
231                let end = std::time::Instant::now();
232                println!("done!: {:?}", end - start);
233            }
234        },
235        SubCommand::Append => {
236            let vo = open_or_create_vector_object::<u32>("u32").unwrap();
237            let start = std::time::Instant::now();
238            match cli.ty {
239                VecTy::U32 => do_append(vo),
240                VecTy::Foo => {
241                    let vo = open_or_create_vector_object::<Foo>("foo").unwrap();
242                    let arena = open_or_create_arena().unwrap();
243                    do_append_foo(vo, arena)
244                }
245            }
246            let end = std::time::Instant::now();
247            println!("done!: {:?}", end - start);
248        }
249        SubCommand::Read => match cli.ty {
250            VecTy::U32 => {
251                let vo = open_or_create_vector_object::<u32>("u32").unwrap();
252                let start = std::time::Instant::now();
253                do_read(vo);
254                let end = std::time::Instant::now();
255                println!("done!: {:?}", end - start);
256            }
257            VecTy::Foo => {
258                let vo = open_or_create_vector_object::<Foo>("foo").unwrap();
259                let start = std::time::Instant::now();
260                do_read(vo);
261                let end = std::time::Instant::now();
262                println!("done!: {:?}", end - start);
263            }
264        },
265        SubCommand::Preload => {
266            let start = std::time::Instant::now();
267            let id = nh.get("/ext/rst", GetFlags::empty()).unwrap().id;
268            sys_object_ctrl(id, twizzler_abi::syscall::ObjectControlCmd::Preload).unwrap();
269            let end = std::time::Instant::now();
270            println!("done!: {:?}", end - start);
271        }
272        SubCommand::Rdb => {
273            println!("in progress");
274        } /*
275          SubCommand::Rdb => {
276              println!("rocksdb test");
277              let start = std::time::Instant::now();
278              let db = rocksdb::DB::open_default("db").unwrap();
279              println!("rocksdb test: put");
280              db.put("test", "value").unwrap();
281              let val = db.get("test").unwrap().unwrap();
282              let val = String::from_utf8(val).unwrap();
283              println!("rocksdb test: get: {}", val);
284              let end = std::time::Instant::now();
285              println!("done!: {:?}", end - start);
286          }
287          */
288    }
289
290    /*
291    let vo = if let Ok(node) = nh.get("/data/ptest-obj-foo", GetFlags::empty()) {
292        println!("reopened: {:?}", node.id);
293        open_vector_object::<Foo>(node.id).unwrap()
294    } else {
295        let vo = create_vector_object().unwrap();
296        println!("new: {:?}", vo.object().id());
297        nh.put("/data/ptest-obj-foo", vo.object().id()).unwrap();
298        vo
299    };
300    for e in &vo {
301        println!("current contents: {:?}", e);
302    }
303    let len = vo.iter().count();
304    println!("pushing items");
305    let start = std::time::Instant::now();
306    let alloc = ArenaObject::new(ObjectBuilder::default().persist()).unwrap();
307    for i in 0..3 {
308        //println!("pushing: {}", i);
309        //vo.push(i).unwrap();
310        vo.push_ctor(|tx| {
311            let foo = Foo {
312                local_data: i + len as u32,
313                data: InvBox::new_in(&tx, i, alloc.allocator()).unwrap(),
314            };
315
316            tx.write(foo)
317        })
318        .unwrap();
319    }
320    let end = std::time::Instant::now();
321    println!("done!: {:?}", end - start);
322    /*
323    for e in &vo {
324        println!("current contents: {:?}", e);
325    }
326    */
327    */
328}