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 } }
289
290 }