mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-04 04:27:34 +00:00
kernel: server: implement DestroyServer(sid)
This implements a syscall to shut down a server. Servers may not be shut down if they have outstanding messages that they have seen but not responded to. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
49c1eacf8c
commit
4830f3eb2c
3 changed files with 297 additions and 47 deletions
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub use crate::arch::process::Thread;
|
||||
use crate::{mem::MemoryManager, services::SystemServices};
|
||||
use core::mem;
|
||||
use xous_kernel::{MemoryAddress, MemoryRange, MemorySize, Message, MessageSender, PID, SID, TID};
|
||||
|
||||
|
|
@ -111,7 +112,7 @@ enum QueuedMessage {
|
|||
u16, /* client PID */
|
||||
u8, /* client TID */
|
||||
u8, /* message index */
|
||||
usize, /* server return address */
|
||||
usize, /* reserved */
|
||||
usize, /* id */
|
||||
usize, /* arg1 */
|
||||
usize, /* arg2 */
|
||||
|
|
@ -122,7 +123,7 @@ enum QueuedMessage {
|
|||
u16, /* client PID */
|
||||
u8, /* client TID */
|
||||
u8, /* message index */
|
||||
usize, /* server return address */
|
||||
usize, /* reserved */
|
||||
usize, /* id */
|
||||
usize, /* arg1 */
|
||||
usize, /* arg2 */
|
||||
|
|
@ -133,9 +134,9 @@ enum QueuedMessage {
|
|||
u16, /* client PID */
|
||||
u8, /* client TID */
|
||||
u8, /* message index */
|
||||
usize, /* reserved */
|
||||
usize, /* client memory address */
|
||||
usize, /* id */
|
||||
usize, /* buf */
|
||||
usize, /* server memory address */
|
||||
usize, /* buf_size */
|
||||
usize, /* offset */
|
||||
usize, /* valid */
|
||||
|
|
@ -144,9 +145,9 @@ enum QueuedMessage {
|
|||
u16, /* client PID */
|
||||
u8, /* client TID */
|
||||
u8, /* message index */
|
||||
usize, /* address of memory base in server */
|
||||
usize, /* client memory address */
|
||||
usize, /* id */
|
||||
usize, /* buf */
|
||||
usize, /* server memory address */
|
||||
usize, /* buf_size */
|
||||
usize, /* offset */
|
||||
usize, /* valid */
|
||||
|
|
@ -155,9 +156,9 @@ enum QueuedMessage {
|
|||
u16, /* client PID */
|
||||
u8, /* client TID */
|
||||
u8, /* message index */
|
||||
usize, /* address of memory base in server */
|
||||
usize, /* client memory address */
|
||||
usize, /* id */
|
||||
usize, /* buf */
|
||||
usize, /* server memory address */
|
||||
usize, /* buf_size */
|
||||
usize, /* offset */
|
||||
usize, /* valid */
|
||||
|
|
@ -169,9 +170,9 @@ enum QueuedMessage {
|
|||
u16, /* client PID */
|
||||
u8, /* client TID */
|
||||
u8, /* message index */
|
||||
usize, /* address of memory base in server */
|
||||
usize, /* client memory address */
|
||||
usize, /* id */
|
||||
usize, /* buf */
|
||||
usize, /* server memory address */
|
||||
usize, /* buf_size */
|
||||
usize, /* offset */
|
||||
usize, /* valid */
|
||||
|
|
@ -183,9 +184,9 @@ enum QueuedMessage {
|
|||
u16, /* client PID */
|
||||
u8, /* client TID */
|
||||
u8, /* message index */
|
||||
usize, /* address of memory base in server */
|
||||
usize, /* client memory address */
|
||||
usize, /* id */
|
||||
usize, /* buf */
|
||||
usize, /* server memory address */
|
||||
usize, /* buf_size */
|
||||
usize, /* offset */
|
||||
usize, /* valid */
|
||||
|
|
@ -197,7 +198,7 @@ enum QueuedMessage {
|
|||
u16, /* client PID */
|
||||
u8, /* client TID */
|
||||
u8, /* message index */
|
||||
usize, /* server return address */
|
||||
usize, /* reserved */
|
||||
usize, /* id */
|
||||
usize, /* arg1 */
|
||||
usize, /* arg2 */
|
||||
|
|
@ -239,6 +240,22 @@ enum QueuedMessage {
|
|||
),
|
||||
}
|
||||
|
||||
impl QueuedMessage {
|
||||
/// Return `true` if this Queued Message is sitting inside of the Server, and
|
||||
/// is therefore waiting to be returned.
|
||||
/// This only indicates messages that have been seen by the Server and have
|
||||
/// not yet been responded to -- Messages that have not yet been seen by the
|
||||
/// Server will return `false`.
|
||||
fn is_in_server(&self) -> bool {
|
||||
match self {
|
||||
&QueuedMessage::WaitingForget(_, _, _, _, _, _)
|
||||
| &QueuedMessage::WaitingReturnMemory(_, _, _, _, _, _)
|
||||
| &QueuedMessage::WaitingReturnScalar(_, _, _, _) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Server {
|
||||
/// Initialize a server in the given option array. This function is
|
||||
/// designed to be called with `new` pointing to an entry in a vec.
|
||||
|
|
@ -260,7 +277,7 @@ impl Server {
|
|||
let queue = unsafe {
|
||||
core::slice::from_raw_parts_mut(
|
||||
_backing.as_mut_ptr() as *mut QueuedMessage,
|
||||
_backing.len() / mem::size_of::<QueuedMessage>(),
|
||||
_backing.len() / mem::size_of::<QueuedMessage>(),
|
||||
)
|
||||
};
|
||||
|
||||
|
|
@ -289,12 +306,182 @@ impl Server {
|
|||
}
|
||||
|
||||
/// Take a current slot and replace it with `None`, clearing out the contents of the queue.
|
||||
pub fn destroy(current: &mut Option<Server>) -> Result<(), xous_kernel::Error> {
|
||||
if let Some(mut server) = current.take() {
|
||||
server.queue_head = 0;
|
||||
server.queue_tail = 0;
|
||||
server.ready_threads = 0;
|
||||
/// Returns an error if the queue has any waiting elements.
|
||||
/// Returns a list of threads that should be readied.
|
||||
pub fn destroy(
|
||||
mut self,
|
||||
ss: &mut SystemServices,
|
||||
) -> Result<(), Self> {
|
||||
|
||||
// First determine if the server has any Waiting messages. That is, any messages
|
||||
// that are currently sitting in the memory space of the Server. These cannot
|
||||
// safely be handled, and will cause an error if we try to mess with them.
|
||||
for queue_entry in self.queue.iter() {
|
||||
if queue_entry.is_in_server() {
|
||||
return Err(self);
|
||||
}
|
||||
}
|
||||
|
||||
// We now know there will be no problems in shutting down this server. Look
|
||||
// through the queue and respond to each message in turn.
|
||||
for entry in self.queue.iter_mut() {
|
||||
match *entry {
|
||||
// If there are `Waiting` messages, then something is seriously wrong because
|
||||
// we already determined above that this wouldn't happen.
|
||||
QueuedMessage::WaitingForget(_, _, _, _, _, _)
|
||||
| QueuedMessage::WaitingReturnMemory(_, _, _, _, _, _)
|
||||
| QueuedMessage::WaitingReturnScalar(_, _, _, _) => panic!("message was waiting"),
|
||||
|
||||
// For `Empty` and `Scalar` messages, all we have to do is ignore them.
|
||||
// The sending process will not be blocked. These messages will be dropped,
|
||||
// and the server will never see them.
|
||||
QueuedMessage::Empty | QueuedMessage::ScalarMessage(_, _, _, _, _, _, _, _, _) => {
|
||||
()
|
||||
}
|
||||
|
||||
// For `Send` messages, the Server has not yet seen these messages. Simply
|
||||
// prevent this memory from getting mapped into the Server and free it.
|
||||
QueuedMessage::MemoryMessageSend(
|
||||
_pid,
|
||||
_tid,
|
||||
_idx,
|
||||
_client_memory_addr,
|
||||
_id,
|
||||
server_memory_addr,
|
||||
memory_length,
|
||||
_offset,
|
||||
_valid,
|
||||
) => {
|
||||
MemoryManager::with_mut(|mm| {
|
||||
let mut result = Ok(xous_kernel::Result::Ok);
|
||||
let virt = server_memory_addr;
|
||||
let size = memory_length;
|
||||
if virt & 0xfff != 0 {
|
||||
return Err(xous_kernel::Error::BadAlignment);
|
||||
}
|
||||
for addr in (virt..(virt + size)).step_by(crate::mem::PAGE_SIZE) {
|
||||
if let Err(e) = mm.unmap_page(addr as *mut usize) {
|
||||
if result.is_ok() {
|
||||
result = Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// For BlockingScalar messages, the client is waiting for a response.
|
||||
// Unblock the client and return an error indicating the server does
|
||||
// not exist.
|
||||
QueuedMessage::BlockingScalarTerminated(pid, tid, _, _, _, _, _, _, _)
|
||||
| QueuedMessage::BlockingScalarMessage(pid, tid, _, _, _, _, _, _, _) => {
|
||||
let pid = PID::new(pid as _).unwrap();
|
||||
let tid = tid as _;
|
||||
|
||||
// Set the return value of the specified thread.
|
||||
ss.set_thread_result(
|
||||
pid,
|
||||
tid,
|
||||
xous_kernel::Result::Error(xous_kernel::Error::ServerNotFound),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Mark it as ready to run.
|
||||
ss.ready_thread(pid, tid).unwrap();
|
||||
}
|
||||
|
||||
QueuedMessage::MemoryMessageROLend(
|
||||
client_pid,
|
||||
client_tid,
|
||||
_idx,
|
||||
client_addr,
|
||||
_id,
|
||||
server_addr,
|
||||
buf_size,
|
||||
_,
|
||||
_,
|
||||
)
|
||||
| QueuedMessage::MemoryMessageRWLend(
|
||||
client_pid,
|
||||
client_tid,
|
||||
_idx,
|
||||
client_addr,
|
||||
_id,
|
||||
server_addr,
|
||||
buf_size,
|
||||
_,
|
||||
_,
|
||||
)
|
||||
| QueuedMessage::MemoryMessageROLendTerminated(
|
||||
client_pid,
|
||||
client_tid,
|
||||
_idx,
|
||||
client_addr,
|
||||
_id,
|
||||
server_addr,
|
||||
buf_size,
|
||||
_,
|
||||
_,
|
||||
)
|
||||
| QueuedMessage::MemoryMessageRWLendTerminated(
|
||||
client_pid,
|
||||
client_tid,
|
||||
_idx,
|
||||
client_addr,
|
||||
_id,
|
||||
server_addr,
|
||||
buf_size,
|
||||
_,
|
||||
_,
|
||||
) => {
|
||||
let client_pid = PID::new(client_pid as _).unwrap();
|
||||
let client_tid = client_tid as _;
|
||||
// Return the memory to the calling process
|
||||
ss.return_memory(
|
||||
server_addr as *mut u8,
|
||||
client_pid,
|
||||
client_tid,
|
||||
client_addr as _,
|
||||
buf_size,
|
||||
)
|
||||
.unwrap();
|
||||
ss.ready_thread(client_pid, client_tid).unwrap();
|
||||
ss.set_thread_result(
|
||||
client_pid,
|
||||
client_tid,
|
||||
xous_kernel::Result::Error(xous_kernel::Error::ServerNotFound),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
*entry = QueuedMessage::Empty;
|
||||
}
|
||||
|
||||
let server_pid = ss.current_pid();
|
||||
|
||||
// Finally, wake up all threads that are waiting on this Server.
|
||||
while let Some(server_tid) = self.take_available_thread() {
|
||||
ss.ready_thread(server_pid, server_tid).unwrap();
|
||||
ss.set_thread_result(
|
||||
server_pid,
|
||||
server_tid,
|
||||
xous_kernel::Result::Error(xous_kernel::Error::ServerNotFound),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// Release the backing memory
|
||||
#[cfg(baremetal)]
|
||||
MemoryManager::with_mut(|mm| {
|
||||
let virt = self.queue.as_mut_ptr() as usize;
|
||||
let size = self.queue.len();
|
||||
for addr in (virt..(virt + size)).step_by(crate::arch::mem::PAGE_SIZE) {
|
||||
mm.unmap_page(addr as *mut usize).unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
// The server should now be destroyed.
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -392,7 +579,8 @@ impl Server {
|
|||
.get_mut(message_index)
|
||||
.ok_or(xous_kernel::Error::BadAddress)?;
|
||||
// klog!("memory in queue[{}]: {:?}", message_index, current_val);
|
||||
let (pid, tid, _idx, server_addr, client_addr, len, forget, is_memory) = match *current_val {
|
||||
let (pid, tid, _idx, server_addr, client_addr, len, forget, is_memory) = match *current_val
|
||||
{
|
||||
QueuedMessage::WaitingReturnMemory(pid, tid, idx, server_addr, client_addr, len) => {
|
||||
(pid, tid, idx, server_addr, client_addr, len, false, true)
|
||||
}
|
||||
|
|
@ -509,7 +697,7 @@ impl Server {
|
|||
idx,
|
||||
client_addr,
|
||||
id,
|
||||
buf,
|
||||
server_addr,
|
||||
buf_size,
|
||||
offset,
|
||||
valid,
|
||||
|
|
@ -520,7 +708,7 @@ impl Server {
|
|||
sender: sender.into(),
|
||||
body: xous_kernel::Message::Borrow(xous_kernel::MemoryMessage {
|
||||
id,
|
||||
buf: MemoryRange::new(buf, buf_size).ok()?,
|
||||
buf: MemoryRange::new(server_addr, buf_size).ok()?,
|
||||
offset: MemorySize::new(offset),
|
||||
valid: MemorySize::new(valid),
|
||||
}),
|
||||
|
|
@ -529,7 +717,7 @@ impl Server {
|
|||
pid,
|
||||
tid,
|
||||
idx,
|
||||
buf,
|
||||
server_addr,
|
||||
client_addr,
|
||||
buf_size,
|
||||
),
|
||||
|
|
@ -541,7 +729,7 @@ impl Server {
|
|||
idx,
|
||||
client_addr,
|
||||
id,
|
||||
buf,
|
||||
server_addr,
|
||||
buf_size,
|
||||
offset,
|
||||
valid,
|
||||
|
|
@ -552,7 +740,7 @@ impl Server {
|
|||
sender: sender.into(),
|
||||
body: xous_kernel::Message::MutableBorrow(xous_kernel::MemoryMessage {
|
||||
id,
|
||||
buf: MemoryRange::new(buf, buf_size).ok()?,
|
||||
buf: MemoryRange::new(server_addr, buf_size).ok()?,
|
||||
offset: MemorySize::new(offset),
|
||||
valid: MemorySize::new(valid),
|
||||
}),
|
||||
|
|
@ -561,7 +749,7 @@ impl Server {
|
|||
pid,
|
||||
tid,
|
||||
idx,
|
||||
buf,
|
||||
server_addr,
|
||||
client_addr,
|
||||
buf_size,
|
||||
),
|
||||
|
|
@ -573,7 +761,7 @@ impl Server {
|
|||
idx,
|
||||
client_addr,
|
||||
id,
|
||||
buf,
|
||||
server_addr,
|
||||
buf_size,
|
||||
offset,
|
||||
valid,
|
||||
|
|
@ -584,7 +772,7 @@ impl Server {
|
|||
sender: sender.into(),
|
||||
body: xous_kernel::Message::Borrow(xous_kernel::MemoryMessage {
|
||||
id,
|
||||
buf: MemoryRange::new(buf, buf_size).ok()?,
|
||||
buf: MemoryRange::new(server_addr, buf_size).ok()?,
|
||||
offset: MemorySize::new(offset),
|
||||
valid: MemorySize::new(valid),
|
||||
}),
|
||||
|
|
@ -593,7 +781,7 @@ impl Server {
|
|||
pid,
|
||||
tid,
|
||||
idx,
|
||||
buf,
|
||||
server_addr,
|
||||
client_addr,
|
||||
buf_size,
|
||||
),
|
||||
|
|
@ -605,7 +793,7 @@ impl Server {
|
|||
idx,
|
||||
client_addr,
|
||||
id,
|
||||
buf,
|
||||
server_addr,
|
||||
buf_size,
|
||||
offset,
|
||||
valid,
|
||||
|
|
@ -616,7 +804,7 @@ impl Server {
|
|||
sender: sender.into(),
|
||||
body: xous_kernel::Message::MutableBorrow(xous_kernel::MemoryMessage {
|
||||
id,
|
||||
buf: MemoryRange::new(buf, buf_size).ok()?,
|
||||
buf: MemoryRange::new(server_addr, buf_size).ok()?,
|
||||
offset: MemorySize::new(offset),
|
||||
valid: MemorySize::new(valid),
|
||||
}),
|
||||
|
|
@ -625,7 +813,7 @@ impl Server {
|
|||
pid,
|
||||
tid,
|
||||
idx,
|
||||
buf,
|
||||
server_addr,
|
||||
client_addr,
|
||||
buf_size,
|
||||
),
|
||||
|
|
@ -666,7 +854,7 @@ impl Server {
|
|||
idx,
|
||||
_reserved,
|
||||
id,
|
||||
buf,
|
||||
server_addr,
|
||||
buf_size,
|
||||
offset,
|
||||
valid,
|
||||
|
|
@ -676,7 +864,7 @@ impl Server {
|
|||
sender: sender.into(),
|
||||
body: xous_kernel::Message::Move(xous_kernel::MemoryMessage {
|
||||
id,
|
||||
buf: MemoryRange::new(buf, buf_size).ok()?,
|
||||
buf: MemoryRange::new(server_addr, buf_size).ok()?,
|
||||
offset: MemorySize::new(offset),
|
||||
valid: MemorySize::new(valid),
|
||||
}),
|
||||
|
|
@ -832,7 +1020,7 @@ impl Server {
|
|||
pid.get() as _,
|
||||
tid as _,
|
||||
self.tail_generation,
|
||||
original_address.map(|x| x.get()).unwrap_or(0),
|
||||
0,
|
||||
msg.id,
|
||||
msg.arg1,
|
||||
msg.arg2,
|
||||
|
|
@ -843,7 +1031,7 @@ impl Server {
|
|||
pid.get() as _,
|
||||
tid as _,
|
||||
self.tail_generation,
|
||||
original_address.map(|x| x.get()).unwrap_or(0),
|
||||
0,
|
||||
msg.id,
|
||||
msg.arg1,
|
||||
msg.arg2,
|
||||
|
|
|
|||
|
|
@ -1047,6 +1047,12 @@ impl SystemServices {
|
|||
}
|
||||
|
||||
let current_pid = self.current_pid();
|
||||
|
||||
// If the dest and src PID is the same, do nothing.
|
||||
if current_pid == dest_pid {
|
||||
return Ok(src_virt);
|
||||
}
|
||||
|
||||
let src_mapping = self.get_process(current_pid)?.mapping;
|
||||
let dest_mapping = self.get_process(dest_pid)?.mapping;
|
||||
crate::mem::MemoryManager::with_mut(|mm| {
|
||||
|
|
@ -1219,12 +1225,10 @@ impl SystemServices {
|
|||
pub fn return_memory(
|
||||
&mut self,
|
||||
src_virt: *mut u8,
|
||||
_src_tid: TID,
|
||||
dest_pid: PID,
|
||||
_dest_tid: TID,
|
||||
dest_virt: *mut u8,
|
||||
len: usize,
|
||||
_buf: MemoryRange,
|
||||
) -> Result<*mut u8, xous_kernel::Error> {
|
||||
// klog!(
|
||||
// "Returning from {}:{} to {}:{}",
|
||||
|
|
@ -1251,6 +1255,10 @@ impl SystemServices {
|
|||
}
|
||||
|
||||
let current_pid = self.current_pid();
|
||||
// If it's within the same process, ignore the operation.
|
||||
if current_pid == dest_pid {
|
||||
return Ok(src_virt);
|
||||
}
|
||||
let src_mapping = self.get_process(current_pid)?.mapping;
|
||||
let dest_mapping = self.get_process(dest_pid)?.mapping;
|
||||
use crate::mem::MemoryManager;
|
||||
|
|
@ -1287,13 +1295,13 @@ impl SystemServices {
|
|||
pub fn return_memory(
|
||||
&mut self,
|
||||
src_virt: *mut u8,
|
||||
_src_tid: TID,
|
||||
dest_pid: PID,
|
||||
dest_tid: TID,
|
||||
_dest_virt: *mut u8,
|
||||
_len: usize,
|
||||
buf: MemoryRange,
|
||||
len: usize,
|
||||
// buf: MemoryRange,
|
||||
) -> Result<*mut u8, xous_kernel::Error> {
|
||||
let buf = MemoryRange::new(src_virt as usize, len)?;
|
||||
let buf = unsafe { core::slice::from_raw_parts(buf.as_ptr(), buf.len()) };
|
||||
let current_pid = self.current_pid();
|
||||
{
|
||||
|
|
@ -1447,6 +1455,55 @@ impl SystemServices {
|
|||
Ok(sid)
|
||||
}
|
||||
|
||||
/// Destroy the provided server ID and disconnect any processes that are
|
||||
/// connected.
|
||||
pub fn destroy_server(&mut self, pid: PID, sid: SID) -> Result<(), xous_kernel::Error> {
|
||||
let mut idx_to_destroy = None;
|
||||
// Look through the server list for a server that matches this SID
|
||||
for (idx, entry) in self.servers.iter().enumerate() {
|
||||
if let Some(server) = entry {
|
||||
if server.sid == sid && server.pid == pid {
|
||||
idx_to_destroy = Some(idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let server_idx = idx_to_destroy.ok_or(xous_kernel::Error::ServerNotFound)?;
|
||||
let server = self.servers[server_idx].take().unwrap();
|
||||
// Try to destroy the server. This will fail if the server
|
||||
// has any outstanding memory requests.
|
||||
server.destroy(self).map_err(|server| {
|
||||
self.servers[server_idx] = Some(server);
|
||||
xous_kernel::Error::ServerQueueFull
|
||||
})?;
|
||||
|
||||
let pid = crate::arch::process::current_pid();
|
||||
// println!("KERNEL({}): Server table: {:?}", _pid.get(), self.servers);
|
||||
// Disconnect this server from all processes.
|
||||
for process in self.processes.iter_mut() {
|
||||
if !process.free() {
|
||||
process.activate().unwrap();
|
||||
ArchProcess::with_inner_mut(|process_inner| {
|
||||
// Look through the connection map for (1) a free slot, and (2) an
|
||||
// existing connection
|
||||
for server_idx_opt in process_inner.connection_map.iter_mut() {
|
||||
if let Some(client_server_idx) = server_idx_opt {
|
||||
if client_server_idx.get() == (server_idx + 2) as _ {
|
||||
*server_idx_opt = None;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Switch back to the primary process.
|
||||
self.get_process(pid).unwrap().activate().unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Connect to a server on behalf of another process.
|
||||
pub fn connect_process_to_server(
|
||||
&mut self,
|
||||
|
|
@ -1767,9 +1824,9 @@ impl SystemServices {
|
|||
/// Calls the provided function with the current inner process state.
|
||||
pub fn shutdown(&mut self) -> Result<(), xous_kernel::Error> {
|
||||
// Destroy all servers. This will cause all queued messages to be lost.
|
||||
for server in &mut self.servers {
|
||||
if server.is_some() {
|
||||
Server::destroy(server).unwrap();
|
||||
for server_idx in 0..self.servers.len() {
|
||||
if let Some(server) = self.servers[server_idx].take() {
|
||||
server.destroy(self).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -323,16 +323,18 @@ fn return_memory(
|
|||
// client_pid,
|
||||
// client_tid
|
||||
// );
|
||||
#[cfg(baremetal)]
|
||||
let src_virt = server_addr.get() as _;
|
||||
#[cfg(not(baremetal))]
|
||||
let src_virt = buf.addr.get() as _;
|
||||
|
||||
// Return the memory to the calling process
|
||||
ss.return_memory(
|
||||
server_addr.get() as _,
|
||||
tid,
|
||||
src_virt,
|
||||
client_pid,
|
||||
client_tid,
|
||||
client_addr.get() as _,
|
||||
len.get(),
|
||||
buf,
|
||||
)?;
|
||||
|
||||
// Unblock the client context to allow it to continue.
|
||||
|
|
@ -844,6 +846,9 @@ pub fn handle_inner(pid: PID, tid: TID, in_irq: bool, call: SysCall) -> SysCallR
|
|||
ss.disconnect_from_server(cid)
|
||||
.and(Ok(xous_kernel::Result::Ok))
|
||||
}),
|
||||
SysCall::DestroyServer(sid) => SystemServices::with_mut(|ss| {
|
||||
ss.destroy_server(pid, sid).and(Ok(xous_kernel::Result::Ok))
|
||||
}),
|
||||
_ => Err(xous_kernel::Error::UnhandledSyscall),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue