use crate::cap::cnode; use crate::cap::object::ObjectTag; use crate::cap::pool::POOL; use crate::cap::table::Rights; use crate::error::KernelError; use crate::ipc::IpcOutcome; use crate::ipc::notification; use crate::proc::PROCESSES; use crate::proc::context::CpuContext; use crate::syscall::{SyscallResult, try_syscall}; pub fn sys_notify_signal(ctx: &mut CpuContext) { let cap_addr = ctx.rdi; let bits = ctx.rsi; let pid = crate::arch::syscall::current_pid(); let mut ptable = PROCESSES.lock(); let cap = { let pool = POOL.lock_after(&ptable); try_syscall!(ctx, cnode::resolve_caller_validate(pid, cap_addr, ObjectTag::Notification, Rights::WRITE, &ptable, &pool)) }; let woke = match notification::do_signal(&cap, bits, &mut ptable) { Ok(woke) => { ctx.rax = SyscallResult::ok().raw(); woke } Err(e) => { ctx.rax = SyscallResult::error(e).raw(); return; } }; drop(ptable); if woke { crate::sched::schedule(ctx); } } pub fn sys_notify_wait(ctx: &mut CpuContext) { let cap_addr = ctx.rdi; let pid = crate::arch::syscall::current_pid(); let mut ptable = PROCESSES.lock(); let cap = { let pool = POOL.lock_after(&ptable); try_syscall!(ctx, cnode::resolve_caller_validate(pid, cap_addr, ObjectTag::Notification, Rights::READ, &ptable, &pool)) }; match notification::do_wait(&cap, pid, &mut ptable) { Ok(IpcOutcome::Done(val)) => { ctx.rax = SyscallResult::ok().raw(); ctx.rdx = val; } Ok(IpcOutcome::Blocked) => { ctx.rax = SyscallResult::ok().raw(); drop(ptable); crate::sched::schedule(ctx); } Err(e) => ctx.rax = SyscallResult::error(e).raw(), } } pub fn sys_notify_poll(ctx: &mut CpuContext) { let cap_addr = ctx.rdi; let pid = crate::arch::syscall::current_pid(); let ptable = PROCESSES.lock(); let cap = { let pool = POOL.lock_after(&ptable); try_syscall!(ctx, cnode::resolve_caller_validate(pid, cap_addr, ObjectTag::Notification, Rights::READ, &ptable, &pool)) }; drop(ptable); match notification::do_poll(&cap) { Ok(val) => { ctx.rax = SyscallResult::ok().raw(); ctx.rdx = val; } Err(e) => ctx.rax = SyscallResult::error(e).raw(), }; } pub fn sys_ntfn_bind(ctx: &mut CpuContext) { let cap_addr = ctx.rdi; let pid = crate::arch::syscall::current_pid(); let mut ptable = PROCESSES.lock(); let (notif_id, notif_gen) = { let pool = POOL.lock_after(&ptable); let cap = try_syscall!(ctx, cnode::resolve_caller_validate(pid, cap_addr, ObjectTag::Notification, Rights::READ, &ptable, &pool)); (cap.object_id(), cap.generation()) }; match ptable.get_mut(pid) { Some(proc) => { proc.bind_notification(notif_id, notif_gen); ctx.rax = SyscallResult::ok().raw(); } None => { ctx.rax = SyscallResult::error(KernelError::InvalidObject).raw(); } } } pub fn sys_ntfn_unbind(ctx: &mut CpuContext) { let pid = crate::arch::syscall::current_pid(); let mut ptable = PROCESSES.lock(); match ptable.get_mut(pid) { Some(proc) => { proc.unbind_notification(); ctx.rax = SyscallResult::ok().raw(); } None => { ctx.rax = SyscallResult::error(KernelError::InvalidObject).raw(); } } }