Nothing to see here, move along
1use crate::cap::cnode;
2use crate::cap::object::ObjectTag;
3use crate::cap::pool::POOL;
4use crate::cap::table::Rights;
5use crate::error::KernelError;
6use crate::ipc::IpcOutcome;
7use crate::ipc::notification;
8use crate::proc::PROCESSES;
9use crate::proc::context::CpuContext;
10use crate::syscall::{SyscallResult, try_syscall};
11
12pub fn sys_notify_signal(ctx: &mut CpuContext) {
13 let cap_addr = ctx.rdi;
14 let bits = ctx.rsi;
15 let pid = crate::arch::syscall::current_pid();
16
17 let mut ptable = PROCESSES.lock();
18 let cap = {
19 let pool = POOL.lock_after(&ptable);
20 try_syscall!(ctx, cnode::resolve_caller_validate(pid, cap_addr, ObjectTag::Notification, Rights::WRITE, &ptable, &pool))
21 };
22
23 let woke = match notification::do_signal(&cap, bits, &mut ptable) {
24 Ok(woke) => {
25 ctx.rax = SyscallResult::ok().raw();
26 woke
27 }
28 Err(e) => {
29 ctx.rax = SyscallResult::error(e).raw();
30 return;
31 }
32 };
33
34 drop(ptable);
35 if woke {
36 crate::sched::schedule(ctx);
37 }
38}
39
40pub fn sys_notify_wait(ctx: &mut CpuContext) {
41 let cap_addr = ctx.rdi;
42 let pid = crate::arch::syscall::current_pid();
43
44 let mut ptable = PROCESSES.lock();
45 let cap = {
46 let pool = POOL.lock_after(&ptable);
47 try_syscall!(ctx, cnode::resolve_caller_validate(pid, cap_addr, ObjectTag::Notification, Rights::READ, &ptable, &pool))
48 };
49
50 match notification::do_wait(&cap, pid, &mut ptable) {
51 Ok(IpcOutcome::Done(val)) => {
52 ctx.rax = SyscallResult::ok().raw();
53 ctx.rdx = val;
54 }
55 Ok(IpcOutcome::Blocked) => {
56 ctx.rax = SyscallResult::ok().raw();
57 drop(ptable);
58 crate::sched::schedule(ctx);
59 }
60 Err(e) => ctx.rax = SyscallResult::error(e).raw(),
61 }
62}
63
64pub fn sys_notify_poll(ctx: &mut CpuContext) {
65 let cap_addr = ctx.rdi;
66 let pid = crate::arch::syscall::current_pid();
67
68 let ptable = PROCESSES.lock();
69 let cap = {
70 let pool = POOL.lock_after(&ptable);
71 try_syscall!(ctx, cnode::resolve_caller_validate(pid, cap_addr, ObjectTag::Notification, Rights::READ, &ptable, &pool))
72 };
73
74 drop(ptable);
75
76 match notification::do_poll(&cap) {
77 Ok(val) => {
78 ctx.rax = SyscallResult::ok().raw();
79 ctx.rdx = val;
80 }
81 Err(e) => ctx.rax = SyscallResult::error(e).raw(),
82 };
83}
84
85pub fn sys_ntfn_bind(ctx: &mut CpuContext) {
86 let cap_addr = ctx.rdi;
87 let pid = crate::arch::syscall::current_pid();
88
89 let mut ptable = PROCESSES.lock();
90 let (notif_id, notif_gen) = {
91 let pool = POOL.lock_after(&ptable);
92 let cap = try_syscall!(ctx, cnode::resolve_caller_validate(pid, cap_addr, ObjectTag::Notification, Rights::READ, &ptable, &pool));
93 (cap.object_id(), cap.generation())
94 };
95
96 match ptable.get_mut(pid) {
97 Some(proc) => {
98 proc.bind_notification(notif_id, notif_gen);
99 ctx.rax = SyscallResult::ok().raw();
100 }
101 None => {
102 ctx.rax = SyscallResult::error(KernelError::InvalidObject).raw();
103 }
104 }
105}
106
107pub fn sys_ntfn_unbind(ctx: &mut CpuContext) {
108 let pid = crate::arch::syscall::current_pid();
109
110 let mut ptable = PROCESSES.lock();
111 match ptable.get_mut(pid) {
112 Some(proc) => {
113 proc.unbind_notification();
114 ctx.rax = SyscallResult::ok().raw();
115 }
116 None => {
117 ctx.rax = SyscallResult::error(KernelError::InvalidObject).raw();
118 }
119 }
120}