-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathlend_mut.rs
More file actions
107 lines (92 loc) · 3.28 KB
/
lend_mut.rs
File metadata and controls
107 lines (92 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// SPDX-FileCopyrightText: 2023 Foundation Devices, Inc. <hello@foundation.xyz>
// SPDX-License-Identifier: GPL-3.0-or-later
use crate::{Server, ServerContext};
/// A [`LendMut`] message handler.
pub trait LendMutHandler<M: LendMut>
where
Self: Server,
{
fn handle(&mut self, msg: M, sender: xous::PID, context: &mut ServerContext<Self>) -> M::Response;
}
/// A message which is simply some mutably borrowed memory.
pub trait LendMut: crate::MessageId + From<SimpleMemoryMessage> + Into<SimpleMemoryMessage> {
type Response: LendMutResponse;
}
pub trait LendMutResponse {
fn from_usize_pair(arg1: usize, arg2: usize) -> Self;
fn to_usize_pair(self) -> (usize, usize);
}
impl LendMutResponse for () {
fn from_usize_pair(_arg1: usize, _arg2: usize) {}
fn to_usize_pair(self) -> (usize, usize) { (0, 0) }
}
impl LendMutResponse for usize {
fn from_usize_pair(arg1: usize, _arg2: usize) -> usize { arg1 }
fn to_usize_pair(self) -> (usize, usize) { (self, 0) }
}
impl<T1: From<usize> + Into<usize>, T2: From<usize> + Into<usize>> LendMutResponse for Result<T1, T2> {
fn from_usize_pair(arg1: usize, arg2: usize) -> Self {
if arg1 == 0 {
Ok(arg2.into())
} else {
Err(arg2.into())
}
}
fn to_usize_pair(self) -> (usize, usize) {
match self {
Ok(o) => (0, o.into()),
Err(e) => (1, e.into()),
}
}
}
/// An easier to use version of [`xous::MemoryMessage`]
pub struct SimpleMemoryMessage {
/// The offset of the buffer. This address will get transformed when the
/// message is moved between processes.
pub buf: xous::MemoryRange,
pub arg1: usize,
pub arg2: usize,
}
impl From<&xous::MemoryMessage> for SimpleMemoryMessage {
fn from(value: &xous::MemoryMessage) -> Self {
Self {
buf: value.buf,
arg1: value.offset.map(|v| v.get()).unwrap_or_default(),
arg2: value.valid.map(|v| v.get()).unwrap_or_default(),
}
}
}
/// Message handler, used by ServerMessages::messages()
pub fn handle_lend_mut<M: LendMut, S: LendMutHandler<M>>(
handler: &mut S,
mut raw: xous::MessageEnvelope,
context: &mut ServerContext<S>,
) {
let xous::Message::MutableBorrow(mem) = &mut raw.body else {
panic!("invalid message: {raw:?}");
};
let msg = M::from(SimpleMemoryMessage::from(&*mem));
let (arg1, arg2) = handler.handle(msg, raw.sender.pid().unwrap(), context).to_usize_pair();
mem.offset = xous::MemoryAddress::new(arg1);
mem.valid = xous::MemoryAddress::new(arg2);
}
/// Send a [`LendMut`] message.
pub fn lend_mut<M: LendMut>(cid: xous::CID, msg: M) -> M::Response {
let msg: SimpleMemoryMessage = msg.into();
let result = xous::send_message(
cid,
xous::Message::MutableBorrow(xous::MemoryMessage {
id: M::ID,
buf: msg.buf,
offset: xous::MemoryAddress::new(msg.arg1),
valid: xous::MemoryAddress::new(msg.arg2),
}),
);
match result {
Ok(xous::Result::MemoryReturned(arg1, arg2)) => M::Response::from_usize_pair(
arg1.map(|v| v.get()).unwrap_or_default(),
arg2.map(|v| v.get()).unwrap_or_default(),
),
_ => panic!("Unexpected return from send_message: {result:?}"),
}
}