From aca442ee8787ddfdf74606663414b7f37081a443 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Thu, 7 Feb 2019 18:19:22 -0800 Subject: [PATCH] First pass at message syscalls --- src/drivers/nulldrv/main.s | 17 ++++++++++ src/kernel/process.cpp | 69 +++++++++++++++++++++++++++++++++++--- src/kernel/process.h | 36 +++++++++++++++++--- src/kernel/syscall.cpp | 25 ++++++++++++++ src/kernel/syscall.h | 2 ++ 5 files changed, 141 insertions(+), 8 deletions(-) diff --git a/src/drivers/nulldrv/main.s b/src/drivers/nulldrv/main.s index fdad2b2..5197242 100644 --- a/src/drivers/nulldrv/main.s +++ b/src/drivers/nulldrv/main.s @@ -9,6 +9,11 @@ _start: mov rax, 1 ; DEBUG syscall int 0xee + cmp r12, 1 + je .dosend + jne .doreceive + +.preloop: mov r11, 0 ; counter mov rbx, 20 ; sleep timeout @@ -31,3 +36,15 @@ _start: mov r11, 0 jmp .loop + +.dosend: + mov rax, 6 ; SEND syscall + mov rdi, 2 ; target is pid 2 + int 0xee + jmp .preloop + +.doreceive: + mov rax, 7 ; RECEIVE syscall + mov rdi, 1 ; source is pid 2 + int 0xee + jmp .preloop diff --git a/src/kernel/process.cpp b/src/kernel/process.cpp index d8b8ac9..3b292f5 100644 --- a/src/kernel/process.cpp +++ b/src/kernel/process.cpp @@ -1,28 +1,65 @@ #include "process.h" +#include "scheduler.h" -void +bool process::wait_on_signal(uint64_t sigmask) { waiting = process_wait::signal; waiting_info = sigmask; flags -= process_flags::ready; + return true; } -void +bool process::wait_on_child(uint32_t pid) { waiting = process_wait::child; waiting_info = pid; flags -= process_flags::ready; + return true; } -void +bool process::wait_on_time(uint64_t time) { waiting = process_wait::time; waiting_info = time; flags -= process_flags::ready; + return true; +} + +bool +process::wait_on_send(uint32_t target_id) +{ + scheduler &s = scheduler::get(); + process *target = s.get_process_by_id(target_id); + if (!target) return false; + + if (!target->wake_on_receive(this)) { + waiting = process_wait::send; + waiting_info = target_id; + flags -= process_flags::ready; + } + + return true; +} + +bool +process::wait_on_receive(uint32_t source_id) +{ + scheduler &s = scheduler::get(); + process *source = s.get_process_by_id(source_id); + if (!source) return false; + + if (!source->wake_on_send(this)) { + waiting = process_wait::receive; + waiting_info = source_id; + flags -= process_flags::ready; + return true; + } + + return false; } bool @@ -49,7 +86,6 @@ process::wake_on_child(process *child) return true; } - bool process::wake_on_time(uint64_t now) { @@ -62,3 +98,28 @@ process::wake_on_time(uint64_t now) return true; } +bool +process::wake_on_send(process *target) +{ + if (waiting != process_wait::send || + waiting_info != target->pid) + return false; + + waiting = process_wait::none; + flags += process_flags::ready; + return true; +} + + +bool +process::wake_on_receive(process *source) +{ + if (waiting != process_wait::receive || + waiting_info != source->pid) + return false; + + waiting = process_wait::none; + flags += process_flags::ready; + return true; +} + diff --git a/src/kernel/process.h b/src/kernel/process.h index 3ba7d90..832cc82 100644 --- a/src/kernel/process.h +++ b/src/kernel/process.h @@ -25,7 +25,9 @@ enum class process_wait : uint8_t none, signal, child, - time + time, + send, + receive }; /// A process @@ -52,15 +54,30 @@ struct process /// Unready this process until it gets a signal /// \arg sigmask A bitfield of signals to wake on - void wait_on_signal(uint64_t sigmask); + /// \returns Whether the process should be rescheduled + bool wait_on_signal(uint64_t sigmask); /// Unready this process until a child exits /// \arg pid PID of the child to wait for, or 0 for any - void wait_on_child(uint32_t pid); + /// \returns Whether the process should be rescheduled + bool wait_on_child(uint32_t pid); /// Unready this process until after the given time /// \arg time The time after which to wake - void wait_on_time(uint64_t time); + /// \returns Whether the process should be rescheduled + bool wait_on_time(uint64_t time); + + /// Try to send to the target process, becoming unready if it + /// is not waiting on receive. + /// \arg target_id The process to send to + /// \returns Whether the process should be rescheduled + bool wait_on_send(uint32_t target_id); + + /// Try to receive from one or more processes, becoming unready + /// if none of them are waiting on a send to this process. + /// \arg source_id The process to receive from + /// \returns Whether the process should be rescheduled + bool wait_on_receive(uint32_t source_id); /// If this process is waiting on the given signal, wake it /// \argument signal The signal sent to the process @@ -76,6 +93,17 @@ struct process /// \argument now The current time /// \returns True if this wake was handled bool wake_on_time(uint64_t now); + + /// If this process is waiting to send to this target, wake it + /// \argument target The target process + /// \returns True if this wake was handled + bool wake_on_send(process *target); + + /// If this process is waiting to receieve from this source, wake it + /// \argument source The process that is sending + /// \returns True if this wake was handled + bool wake_on_receive(process *source); + }; using process_list = kutil::linked_list; diff --git a/src/kernel/syscall.cpp b/src/kernel/syscall.cpp index a50d2cc..378432f 100644 --- a/src/kernel/syscall.cpp +++ b/src/kernel/syscall.cpp @@ -92,6 +92,31 @@ syscall_dispatch(uintptr_t return_rsp, cpu_state ®s) regs.rax = p->pid; break; + case syscall::send: + { + uint32_t target = regs.rdi; + + cons->set_color(11); + cons->printf("\nProcess %u: Received SEND syscall, target %u\n", p->pid, target); + cons->set_color(); + + if (p->wait_on_send(target)) + return_rsp = s.schedule(return_rsp); + } + break; + + case syscall::receive: + { + uint32_t source = regs.rdi; + + cons->set_color(11); + cons->printf("\nProcess %u: Received RECEIVE syscall, source %u\n", p->pid, source); + cons->set_color(); + + if (p->wait_on_receive(source)) + return_rsp = s.schedule(return_rsp); + } + break; default: cons->set_color(9); diff --git a/src/kernel/syscall.h b/src/kernel/syscall.h index a1f27c5..18b65b1 100644 --- a/src/kernel/syscall.h +++ b/src/kernel/syscall.h @@ -12,6 +12,8 @@ enum class syscall : uint64_t pause, sleep, getpid, + send, + receive, last_syscall };