1#![feature(naked_functions)]
2
3use std::{collections::BTreeMap, sync::Mutex, time::Instant};
4
5use twizzler_abi::{
6 object::ObjID,
7 syscall::{sys_object_ctrl, ObjectControlCmd},
8};
9use twizzler_rt_abi::{
10 object::{MapFlags, ObjectHandle},
11 Result,
12};
13
14#[derive(Debug, Clone, Copy)]
15#[repr(C)]
16pub struct CachedStats {
17 pub id: ObjID,
18 pub start: Instant,
19 pub flags: MapFlags,
20}
21
22type Key = (ObjID, MapFlags);
23
24struct HeldObject {
25 start: Instant,
26 handle: ObjectHandle,
27}
28
29impl HeldObject {
30 fn new(handle: ObjectHandle) -> Self {
31 Self {
32 start: Instant::now(),
33 handle,
34 }
35 }
36}
37
38struct CacheState {
39 map: BTreeMap<Key, HeldObject>,
40}
41
42impl CacheState {
43 const fn new() -> Self {
44 Self {
45 map: BTreeMap::new(),
46 }
47 }
48}
49
50static STATE: Mutex<CacheState> = Mutex::new(CacheState::new());
51
52#[secgate::secure_gate]
53pub fn hold(id: ObjID, flags: MapFlags) -> Result<bool> {
54 let handle = twizzler_rt_abi::object::twz_rt_map_object(id, flags)?;
55 let mut state = STATE.lock().unwrap();
56 Ok(state
57 .map
58 .insert((id, flags), HeldObject::new(handle))
59 .is_some())
60}
61
62#[secgate::secure_gate]
63pub fn drop(id: ObjID, flags: MapFlags) -> Result<bool> {
64 let mut state = STATE.lock().unwrap();
65 Ok(state.map.remove(&(id, flags)).is_some())
66}
67
68#[secgate::secure_gate]
69pub fn preload(id: ObjID) -> Result<()> {
70 sys_object_ctrl(id, ObjectControlCmd::Preload)
71}
72
73#[secgate::secure_gate]
74pub fn stat(_id: ObjID) -> Result<()> {
75 Ok(())
76}
77
78#[secgate::secure_gate]
79pub fn list_nth(nth: u64) -> Result<Option<CachedStats>> {
80 let state = STATE.lock().unwrap();
81 if let Some(v) = state.map.values().nth(nth as usize) {
82 Ok(Some(CachedStats {
83 id: v.handle.id(),
84 flags: v.handle.map_flags(),
85 start: v.start,
86 }))
87 } else {
88 Ok(None)
89 }
90}